diff --git a/src/perspective3d.cpp b/src/perspective3d.cpp
index dd05ec7c7cef6ca7563e75782a2a78ce25200908..2137449373735c8a62dfec0f67fb6b95b37692f1 100644 (file)
--- a/src/perspective3d.cpp
+++ b/src/perspective3d.cpp
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
* vanishing points in the given directions.
{
Perspective3D::remove_perspective (this);
+ // Remove the VPs from their draggers
+ SPEventContext *ec = inkscape_active_event_context();
+ if (SP_IS_3DBOX_CONTEXT (ec)) {
+ SP3DBoxContext *bc = SP_3DBOX_CONTEXT (ec);
+ // we need to check if there are any draggers because the selection
+ // is temporarily empty during duplication of boxes, e.g.
+ if (bc->_vpdrag->draggers != NULL) {
+ /***
+ g_assert (bc->_vpdrag->getDraggerFor (*vp_x) != NULL);
+ g_assert (bc->_vpdrag->getDraggerFor (*vp_y) != NULL);
+ g_assert (bc->_vpdrag->getDraggerFor (*vp_z) != NULL);
+ bc->_vpdrag->getDraggerFor (*vp_x)->removeVP (vp_x);
+ bc->_vpdrag->getDraggerFor (*vp_y)->removeVP (vp_y);
+ bc->_vpdrag->getDraggerFor (*vp_z)->removeVP (vp_z);
+ ***/
+ // TODO: the temporary perspective created when building boxes is not linked to any dragger, hence
+ // we need to do the following checks. Maybe it would be better to not create a temporary
+ // perspective at all but simply compare the VPs manually in sp_3dbox_build.
+ VPDragger * dragger;
+ dragger = bc->_vpdrag->getDraggerFor (*vp_x);
+ if (dragger)
+ dragger->removeVP (vp_x);
+ dragger = bc->_vpdrag->getDraggerFor (*vp_y);
+ if (dragger)
+ dragger->removeVP (vp_y);
+ dragger = bc->_vpdrag->getDraggerFor (*vp_z);
+ if (dragger)
+ dragger->removeVP (vp_z);
+ }
+ }
+
delete vp_x;
delete vp_y;
delete vp_z;
}
bool
-Perspective3D::operator==(Perspective3D const &other)
+Perspective3D::operator==(Perspective3D const &other) const
{
// Two perspectives are equal iff their vanishing points coincide and have identical states
return (*vp_x == *other.vp_x && *vp_y == *other.vp_y && *vp_z == *other.vp_z);
}
+bool
+Perspective3D::has_vanishing_point (VanishingPoint *vp)
+{
+ return (vp == vp_x || vp == vp_y || vp == vp_z);
+}
+
VanishingPoint *
Perspective3D::get_vanishing_point (Box3D::Axis const dir)
{
@@ -145,6 +199,17 @@ Perspective3D::set_vanishing_point (Box3D::Axis const dir, VanishingPoint const
}
}
+Axis
+Perspective3D::get_axis_of_VP (VanishingPoint *vp)
+{
+ if (vp == vp_x) return X;
+ if (vp == vp_y) return Y;
+ if (vp == vp_z) return Z;
+
+ g_warning ("Vanishing point not present in the perspective.\n");
+ return NONE;
+}
+
void
Perspective3D::set_vanishing_point (Box3D::Axis const dir, gdouble pt_x, gdouble pt_y, gdouble dir_x, gdouble dir_y, VPState st)
{
}
bool
-Perspective3D::has_box (const SP3DBox *box)
+Perspective3D::has_box (const SP3DBox *box) const
{
return (g_slist_find (this->boxes, box) != NULL);
}
+bool
+Perspective3D::all_boxes_occur_in_list (GSList *boxes_to_do)
+{
+ for (GSList *i = boxes; i != NULL; i = i->next) {
+ if (!g_slist_find (boxes_to_do, i->data)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+GSList *
+Perspective3D::boxes_occurring_in_list (GSList * list_of_boxes)
+{
+ GSList * result = NULL;
+ for (GSList *i = list_of_boxes; i != NULL; i = i->next) {
+ if (this->has_box (SP_3DBOX (i->data))) {
+ result = g_slist_prepend (result, i->data);
+ }
+ }
+ // we reverse so as to retain the same order as in list_of_boxes
+ return g_slist_reverse (result);
+}
+
/**
* Update the shape of a box after a handle was dragged or a VP was changed, according to the stored ratios.
*/
}
}
+// swallow the list of boxes from the other perspective and delete it
+void
+Perspective3D::absorb (Perspective3D *other)
+{
+ g_return_if_fail (*this == *other);
+
+ // FIXME: Is copying necessary? Is other->boxes invalidated when other is deleted below?
+ this->boxes = g_slist_concat (this->boxes, g_slist_copy (other->boxes));
+
+ // Should we delete the other perspective here or at the place from where absorb() is called?
+ delete other;
+ other = NULL;
+}
+
// FIXME: We get compiler errors when we try to move the code from sp_3dbox_get_perspective_string to this function
/***
gchar *