Code

Refactoring of 3D box tool, mainly to avoid unnecessary creation of perspectives.
[inkscape.git] / src / vanishing-point.cpp
index 8bedaec5d479b8545e3615ff54bb42daba2741f8..78ceec4671178a2bf4fb33535d7f0137eeab7af4 100644 (file)
@@ -21,8 +21,7 @@
 #include "event-context.h"
 #include "xml/repr.h"
 #include "perspective-line.h"
-
-#include "knotholder.h" // FIXME: can we avoid direct access to knotholder_update_knots?
+#include "shape-editor.h"
 
 namespace Box3D {
 
@@ -77,12 +76,12 @@ have_VPs_of_same_perspective (VPDragger *dr1, VPDragger *dr2)
 }
 
 static void
-vp_knot_moved_handler (SPKnot */*knot*/, NR::Point const *ppointer, guint state, gpointer data)
+vp_knot_moved_handler (SPKnot */*knot*/, Geom::Point const *ppointer, guint state, gpointer data)
 {
     VPDragger *dragger = (VPDragger *) data;
     VPDrag *drag = dragger->parent;
 
-    NR::Point p = *ppointer;
+    Geom::Point p = *ppointer;
 
     // FIXME: take from prefs
     double snap_dist = SNAP_DIST / inkscape_active_desktop()->current_zoom();
@@ -94,17 +93,8 @@ vp_knot_moved_handler (SPKnot */*knot*/, NR::Point const *ppointer, guint state,
     if (!dragger->dragging_started && (state & GDK_SHIFT_MASK)) {
         /* with Shift; if there is more than one box linked to this VP
            we need to split it and create a new perspective */
-        //g_print ("Number of boxes in dragger: %d\n", dragger->numberOfBoxes());
         if (dragger->numberOfBoxes() > 1) { // FIXME: Don't do anything if *all* boxes of a VP are selected
-            //g_print ("We need to split the VPDragger\n");
             std::set<VanishingPoint*, less_ptr> sel_vps = dragger->VPsOfSelectedBoxes();
-            /**
-            g_print ("===== VPs of selected boxes: ===========================\n");
-            for (std::set<VanishingPoint*, less_ptr>::iterator i = sel_vps.begin(); i != sel_vps.end(); ++i) {
-                (*i)->printPt();
-            }
-            g_print ("========================================================\n");
-            **/
 
             std::list<SPBox3D *> sel_boxes;
             for (std::set<VanishingPoint*, less_ptr>::iterator vp = sel_vps.begin(); vp != sel_vps.end(); ++vp) {
@@ -113,18 +103,16 @@ vp_knot_moved_handler (SPKnot */*knot*/, NR::Point const *ppointer, guint state,
                 sel_boxes = (*vp)->selectedBoxes(sp_desktop_selection(inkscape_active_desktop()));
 
                 // we create a new perspective ...
-                Persp3D *new_persp = persp3d_create_xml_element (dragger->parent->document, old_persp);
+                Persp3D *new_persp = persp3d_create_xml_element (dragger->parent->document, old_persp->perspective_impl);
 
                 /* ... unlink the boxes from the old one and
                    FIXME: We need to unlink the _un_selected boxes of each VP so that
                           the correct boxes are kept with the VP being moved */
                 std::list<SPBox3D *> bx_lst = persp3d_list_of_boxes(old_persp);
                 for (std::list<SPBox3D *>::iterator i = bx_lst.begin(); i != bx_lst.end(); ++i) {
-                    //g_print ("Iterating over box #%d\n", (*i)->my_counter);
                     if (std::find(sel_boxes.begin(), sel_boxes.end(), *i) == sel_boxes.end()) {
                         /* if a box in the VP is unselected, move it to the
                            newly created perspective so that it doesn't get dragged **/
-                        //g_print ("   switching box #%d to new perspective.\n", (*i)->my_counter);
                         box3d_switch_perspectives(*i, old_persp, new_persp);
                     }
                 }
@@ -141,7 +129,7 @@ vp_knot_moved_handler (SPKnot */*knot*/, NR::Point const *ppointer, guint state,
         // without Shift; see if we need to snap to another dragger
         for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) {
             VPDragger *d_new = (VPDragger *) di->data;
-            if ((d_new != dragger) && (NR::L2 (d_new->point - p) < snap_dist)) {
+            if ((d_new != dragger) && (Geom::L2 (d_new->point - p) < snap_dist)) {
                 if (have_VPs_of_same_perspective (dragger, d_new)) {
                     // this would result in degenerate boxes, which we disallow for the time being
                     continue;
@@ -165,7 +153,6 @@ vp_knot_moved_handler (SPKnot */*knot*/, NR::Point const *ppointer, guint state,
                 d_new->mergePerspectives();
 
                 // TODO: Update the new merged dragger
-                //d_new->updateKnotShape ();
                 d_new->updateTip();
 
                 d_new->parent->updateBoxDisplays (); // FIXME: Only update boxes in current dragger!
@@ -198,18 +185,6 @@ vp_knot_moved_handler (SPKnot */*knot*/, NR::Point const *ppointer, guint state,
     dragger->dragging_started = true;
 }
 
-/* helpful for debugging */
-static void
-vp_knot_clicked_handler(SPKnot */*knot*/, guint /*state*/, gpointer data)
-{
-    VPDragger *dragger = (VPDragger *) data;
-    g_print ("\nVPDragger contains the following VPs: ");
-    for (std::list<VanishingPoint>::iterator i = dragger->vps.begin(); i != dragger->vps.end(); ++i) {
-        g_print("%d (%d)  ", (*i).my_counter, (*i).get_perspective()->my_counter);
-    }
-    g_print("\n");
-}
-
 void
 vp_knot_grabbed_handler (SPKnot */*knot*/, unsigned int /*state*/, gpointer data)
 {
@@ -224,8 +199,6 @@ vp_knot_ungrabbed_handler (SPKnot *knot, guint /*state*/, gpointer data)
 {
     VPDragger *dragger = (VPDragger *) data;
 
-    //sp_canvas_end_forced_full_redraws(dragger->parent->desktop->canvas);
-
     dragger->point_original = dragger->point = knot->pos;
 
     dragger->dragging_started = false;
@@ -237,7 +210,6 @@ vp_knot_ungrabbed_handler (SPKnot *knot, guint /*state*/, gpointer data)
     }
 
     dragger->parent->updateDraggers ();
-    //dragger->updateBoxReprs ();
     dragger->parent->updateLines ();
     dragger->parent->updateBoxHandles ();
 
@@ -258,7 +230,7 @@ unsigned int VanishingPoint::global_counter = 0;
 void
 VanishingPoint::set_pos(Proj::Pt2 const &pt) {
     g_return_if_fail (_persp);
-    _persp->tmat.set_image_pt (_axis, pt);
+    _persp->perspective_impl->tmat.set_image_pt (_axis, pt);
 }
 
 std::list<SPBox3D *>
@@ -275,10 +247,8 @@ VanishingPoint::selectedBoxes(Inkscape::Selection *sel) {
     return sel_boxes;
 }
 
-VPDragger::VPDragger(VPDrag *parent, NR::Point p, VanishingPoint &vp)
+VPDragger::VPDragger(VPDrag *parent, Geom::Point p, VanishingPoint &vp)
 {
-    //this->vps = NULL;
-
     this->parent = parent;
 
     this->point = p;
@@ -295,43 +265,27 @@ VPDragger::VPDragger(VPDrag *parent, NR::Point p, VanishingPoint &vp)
         sp_knot_update_ctrl(this->knot);
 
         // move knot to the given point
-        sp_knot_set_position (this->knot, &this->point, SP_KNOT_STATE_NORMAL);
+        sp_knot_set_position (this->knot, this->point, SP_KNOT_STATE_NORMAL);
         sp_knot_show (this->knot);
 
         // connect knot's signals
         g_signal_connect (G_OBJECT (this->knot), "moved", G_CALLBACK (vp_knot_moved_handler), this);
-        g_signal_connect (G_OBJECT (this->knot), "clicked", G_CALLBACK (vp_knot_clicked_handler), this);
         g_signal_connect (G_OBJECT (this->knot), "grabbed", G_CALLBACK (vp_knot_grabbed_handler), this);
         g_signal_connect (G_OBJECT (this->knot), "ungrabbed", G_CALLBACK (vp_knot_ungrabbed_handler), this);
-        /***
-        g_signal_connect (G_OBJECT (this->knot), "doubleclicked", G_CALLBACK (vp_knot_doubleclicked_handler), this);
-        ***/
 
         // add the initial VP (which may be NULL!)
         this->addVP (vp);
-        //updateKnotShape();
     }
 }
 
 VPDragger::~VPDragger()
 {
-    // unselect if it was selected
-    //this->parent->setDeselected(this);
-
     // disconnect signals
     g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (vp_knot_moved_handler), this);
-    g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (vp_knot_clicked_handler), this);
     g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (vp_knot_grabbed_handler), this);
     g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (vp_knot_ungrabbed_handler), this);
-    /***
-    g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (vp_knot_doubleclicked_handler), this);
-    ***/
-
     /* unref should call destroy */
     g_object_unref (G_OBJECT (this->knot));
-
-    //g_slist_free (this->vps);
-    //this->vps = NULL;
 }
 
 /**
@@ -380,7 +334,6 @@ VPDragger::updateTip ()
 void
 VPDragger::addVP (VanishingPoint &vp, bool update_pos)
 {
-    //if (!vp.is_finite() || g_slist_find (this->vps, vp)) {
     if (!vp.is_finite() || std::find (vps.begin(), vps.end(), vp) != vps.end()) {
         // don't add infinite VPs; don't add the same VP twice
         return;
@@ -389,9 +342,7 @@ VPDragger::addVP (VanishingPoint &vp, bool update_pos)
     if (update_pos) {
         vp.set_pos (this->point);
     }
-    //this->vps = g_slist_prepend (this->vps, vp);
     this->vps.push_front (vp);
-    //this->persps.include (vp.get_perspective());
 
     this->updateTip();
 }
@@ -488,7 +439,7 @@ VPDragger::updateBoxDisplays ()
 }
 
 void
-VPDragger::updateVPs (NR::Point const &pt)
+VPDragger::updateVPs (Geom::Point const &pt)
 {
     for (std::list<VanishingPoint>::iterator i = this->vps.begin(); i != this->vps.end(); ++i) {
         (*i).set_pos (pt);
@@ -505,7 +456,7 @@ VPDragger::updateZOrders ()
 
 void
 VPDragger::printVPs() {
-    g_print ("VPDragger at position (%f, %f):\n", point[NR::X], point[NR::Y]);
+    g_print ("VPDragger at position (%f, %f):\n", point[Geom::X], point[Geom::Y]);
     for (std::list<VanishingPoint>::iterator i = this->vps.begin(); i != this->vps.end(); ++i) {
         g_print ("    VP %s\n", (*i).axisString());
     }
@@ -521,7 +472,6 @@ VPDrag::VPDrag (SPDocument *document)
     this->show_lines = true;
     this->front_or_rear_lines = 0x1;
 
-    //this->selected = NULL;
     this->dragging = false;
 
     this->sel_changed_connection = this->selection->connectChanged(
@@ -650,7 +600,7 @@ void
 VPDrag::updateBoxHandles ()
 {
     // FIXME: Is there a way to update the knots without accessing the
-    //        (previously) statically linked function knotholder_update_knots?
+    //        (previously) statically linked function KnotHolder::update_knots?
 
     GSList *sel = (GSList *) selection->itemList();
     if (!sel)
@@ -663,8 +613,8 @@ VPDrag::updateBoxHandles ()
 
     SPEventContext *ec = inkscape_active_event_context();
     g_assert (ec != NULL);
-    if (ec->shape_knot_holder != NULL) {
-        knotholder_update_knots(ec->shape_knot_holder, (SPItem *) sel->data);
+    if (ec->shape_editor != NULL) {
+        ec->shape_editor->update_knotholder();
     }
 }
 
@@ -706,14 +656,14 @@ VPDrag::drawLinesForFace (const SPBox3D *box, Proj::Axis axis) //, guint corner1
         default: g_assert_not_reached();
     }
 
-    NR::Point corner1, corner2, corner3, corner4;
+    Geom::Point corner1, corner2, corner3, corner4;
     box3d_corners_for_PLs (box, axis, corner1, corner2, corner3, corner4);
 
     g_return_if_fail (box3d_get_perspective(box));
     Proj::Pt2 vp = persp3d_get_VP (box3d_get_perspective(box), axis);
     if (vp.is_finite()) {
         // draw perspective lines for finite VPs
-        NR::Point pt = vp.affine();
+        Geom::Point pt = vp.affine();
         if (this->front_or_rear_lines & 0x1) {
             // draw 'front' perspective lines
             this->addLine (corner1, pt, color);
@@ -726,7 +676,7 @@ VPDrag::drawLinesForFace (const SPBox3D *box, Proj::Axis axis) //, guint corner1
         }
     } else {
         // draw perspective lines for infinite VPs
-        NR::Maybe<NR::Point> pt1, pt2, pt3, pt4;
+        boost::optional<Geom::Point> pt1, pt2, pt3, pt4;
         Persp3D *persp = box3d_get_perspective(box);
         SPDesktop *desktop = inkscape_active_desktop (); // FIXME: Store the desktop in VPDrag
         Box3D::PerspectiveLine pl (corner1, axis, persp);
@@ -770,14 +720,13 @@ VPDrag::addDragger (VanishingPoint &vp)
         // don't create draggers for infinite vanishing points
         return;
     }
-    NR::Point p = vp.get_pos();
+    Geom::Point p = vp.get_pos();
 
     for (GList *i = this->draggers; i != NULL; i = i->next) {
         VPDragger *dragger = (VPDragger *) i->data;
-        if (NR::L2 (dragger->point - p) < MERGE_DIST) {
+        if (Geom::L2 (dragger->point - p) < MERGE_DIST) {
             // distance is small, merge this draggable into dragger, no need to create new dragger
             dragger->addVP (vp);
-            //dragger->updateKnotShape();
             return;
         }
     }
@@ -805,7 +754,7 @@ VPDrag::swap_perspectives_of_VPs(Persp3D *persp2, Persp3D *persp1)
 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)
+VPDrag::addLine (Geom::Point p1, Geom::Point p2, guint32 rgba)
 {
     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);