diff --git a/src/box3d.cpp b/src/box3d.cpp
index 0f672aab25d7ba243cd0b54297dd4ecc69ac60b4..ff00a795c57505d50c8475fa83ed835cd16e4740 100644 (file)
--- a/src/box3d.cpp
+++ b/src/box3d.cpp
{
if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
SP3DBox *box = SP_3DBOX(object);
- sp_3dbox_link_to_existing_paths (box, SP_OBJECT_REPR(object));
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(object);
+ sp_3dbox_link_to_existing_paths (box, repr);
+ SPEventContext *ec = inkscape_active_event_context();
+ if (SP_IS_3DBOX_CONTEXT (ec)) {
+ SP_3DBOX_CONTEXT (ec)->_vpdrag->updateDraggers();
+ // FIXME: Should we update the corners here, too? Maybe this is the reason why the handles
+ // are off after an undo/redo! On the other hand, if we do so we get warnings about
+ // updates occuring while other updats are in progress ...
+ }
}
/* Invoke parent method */
((SPObjectClass *) (parent_class))->update(object, ctx, flags);
}
-
-
static Inkscape::XML::Node *sp_3dbox_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
{
SP3DBox *box = SP_3DBOX(object);
@@ -439,7 +445,7 @@ sp_3dbox_corner_angle_to_VP (SP3DBox *box, Box3D::Axis axis, guint extreme_corne
bool sp_3dbox_recompute_z_orders (SP3DBox *box)
{
- guint new_z_orders[6];
+ gint new_z_orders[6];
// 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);
@@ -636,13 +642,9 @@ static void sp_3dbox_corner_configuration (SP3DBox *box, std::vector<gint> &on_h
/* returns true if there was a change in the z-orders (which triggers an update of the repr) */
static bool sp_3dbox_recompute_z_orders_by_corner_configuration (SP3DBox *box)
{
- guint new_z_orders[6];
+ gint new_z_orders[6];
Box3D::Axis front_rear_axis = Box3D::Z;
- Box3D::Axis axis1 = Box3D::get_remaining_axes (front_rear_axis).first;
- Box3D::Axis axis2 = Box3D::get_remaining_axes (front_rear_axis).second;
- Box3D::Axis front_plane = Box3D::orth_plane_or_axis (front_rear_axis);
-
std::vector<gint> on_hull;
std::vector<gint> inside_hull;
std::vector<gint> visible_faces;
@@ -670,24 +672,24 @@ static bool sp_3dbox_recompute_z_orders_by_corner_configuration (SP3DBox *box)
guint visible_front_corner = (((c_cmp & front_rear_axis) == (c1 & front_rear_axis)) ? c1 : c2);
visible_faces = sp_3dbox_faces_meeting_in_corner (visible_front_corner);
} else {
- g_print ("Warning: Unhandled case. Current z-orders remain unchanged.\n");
+ /* Under what conditions do we end up here? Can we safely ignore this case? */
return false;
}
break;
}
default:
- g_print ("Warning: Unhandled case. Current z-orders are not changed.\n");
+ /* Under what conditions do we end up here? Can we safely ignore this case? */
return false;
}
- // check for weird corner configurations that cannot be handled by the above code
+ /* catch weird corner configurations; these should be theoretically impossible, but maybe
+ occur in (almost) degenerate cases due to rounding errors, for example */
if (std::find (visible_faces.begin(), visible_faces.end(), -1) != visible_faces.end()) {
- g_warning ("Theoretically impossible corner configuration\n");
return false;
}
- // sort the list of visible faces for later use (although it may be already sorted anyway)
+ /* sort the list of visible faces for later use (although it may be already sorted anyway) */
std::sort (visible_faces.begin(), visible_faces.end());
std::vector<gint> invisible_faces;
std::swap (visible_faces, invisible_faces);
if (!sp_3dbox_is_subset_or_superset (visible_faces, box->currently_visible_faces) &&
!sp_3dbox_differ_by_opposite_faces (visible_faces, box->currently_visible_faces)) {
- // FIXME: Hopefully this case is only caused by rounding errors or something similar;
- // does it need further investigation?
- g_warning ("Can't find out which faces are visible and which aren't ...\n");
+ /* Hopefully this case is only caused by rounding errors or something similar;
+ does it need further investigation? */
return false;
}
}
}
}
+void
+sp_3dbox_reshape_after_VP_rotation (SP3DBox *box, Box3D::Axis axis)
+{
+ Box3D::Perspective3D *persp = inkscape_active_document()->get_persp_of_box (box);
+ Box3D::VanishingPoint *vp = persp->get_vanishing_point (axis);
+
+ guint c1 = (axis == Box3D::Z) ? 1 : sp_3dbox_get_front_corner_id (box); // hack
+ guint c2 = c1 ^ axis;
+ NR::Point v = box->corners[c1] - box->corners[c2];
+ double dist = NR::L2 (v) * ((NR::dot (v, vp->v_dir) < 0) ? 1 : -1); // "directed" distance
+
+ Box3D::PerspectiveLine pline (box->corners[c1], axis, persp);
+ NR::Point pt = pline.point_from_lambda (dist);
+
+ sp_3dbox_move_corner_in_Z_direction (box, c2, pt, axis == Box3D::Z);
+}
+
void
sp_3dbox_move_corner_in_XY_plane (SP3DBox *box, guint id, NR::Point pt, Box3D::Axis axes)
{
@@ -1026,6 +1044,9 @@ sp_3dbox_new_midpoints (Box3D::Perspective3D *persp, Box3D::Axis axis, NR::Point
// FIXME: cr == 1 is a degenerate case; how should we deal with it?
return std::make_pair (NR::Point (0,0), NR::Point (0,0));
}
+ if (cr1 == NR_HUGE) {
+ return std::make_pair (A, B);
+ }
Box3D::PerspectiveLine pl (M0, axis, persp);
NR::Point B_new = pl.pt_with_given_cross_ratio (M0, M, cr1 / (cr1 - 1));
NR::Point A_new = pl.pt_with_given_cross_ratio (M0, M, 1 - cr2);