X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fvanishing-point.h;h=9fcb6bb46d6440a0e35bf8b67311add2df68d78f;hb=030609cb99174ea85e69635c494ccaaaa20b2ac5;hp=3be5d085ee35ce3733bf3d74e7272b2ea06eef2c;hpb=9a868a59ec493f756a456bfd2c6706a347bc5682;p=inkscape.git diff --git a/src/vanishing-point.h b/src/vanishing-point.h index 3be5d085e..9fcb6bb46 100644 --- a/src/vanishing-point.h +++ b/src/vanishing-point.h @@ -12,8 +12,17 @@ #ifndef SEEN_VANISHING_POINT_H #define SEEN_VANISHING_POINT_H -#include "libnr/nr-point.h" -#include "line-geometry.h" +#include +#include <2geom/point.h> +#include "knot.h" +#include "selection.h" +#include "axis-manip.h" +#include "inkscape.h" +#include "persp3d.h" +#include "box3d.h" +#include "persp3d-reference.h" + +class SPBox3D; namespace Box3D { @@ -22,68 +31,182 @@ enum VPState { VP_INFINITE // perspective lines are parallel }; -// The X-/Y-/Z-axis corresponds to the first/second/third digit -// in binary representation, respectively. -enum Axis { - X = 1, - Y = 2, - Z = 4, - NONE = 0 +/* VanishingPoint is a simple wrapper class to easily extract VP data from perspectives. + * A VanishingPoint represents a VP in a certain direction (X, Y, Z) of a single perspective. + * In particular, it can potentially have more than one box linked to it (although in facth they + * are rather linked to the parent perspective). + */ +// FIXME: Don't store the box in the VP but rather the perspective (and link the box to it)!! +class VanishingPoint { +public: + VanishingPoint() : my_counter(VanishingPoint::global_counter++), _persp(NULL), _axis(Proj::NONE) {} + VanishingPoint(Persp3D *persp, Proj::Axis axis) : my_counter(VanishingPoint::global_counter++), _persp(persp), _axis(axis) {} + VanishingPoint(const VanishingPoint &other) : my_counter(VanishingPoint::global_counter++), _persp(other._persp), _axis(other._axis) {} + + inline VanishingPoint &operator=(VanishingPoint const &rhs) { + _persp = rhs._persp; + _axis = rhs._axis; + return *this; + } + inline bool operator==(VanishingPoint const &rhs) const { + /* vanishing points coincide if they belong to the same perspective */ + return (_persp == rhs._persp && _axis == rhs._axis); + } + + inline bool operator<(VanishingPoint const &rhs) const { + return my_counter < rhs.my_counter; + } + + inline void set(Persp3D *persp, Proj::Axis axis) { + _persp = persp; + _axis = axis; + } + void set_pos(Proj::Pt2 const &pt); + inline bool is_finite() const { + g_return_val_if_fail (_persp, false); + return persp3d_get_VP (_persp, _axis).is_finite(); + } + inline Geom::Point get_pos() const { + g_return_val_if_fail (_persp, Geom::Point (NR_HUGE, NR_HUGE)); + return persp3d_get_VP (_persp,_axis).affine(); + } + inline Persp3D * get_perspective() const { + return _persp; + } + inline Persp3D * set_perspective(Persp3D *persp) { + return _persp = persp; + } + + inline bool hasBox (SPBox3D *box) { + return persp3d_has_box(_persp, box); + } + inline unsigned int numberOfBoxes() const { + return persp3d_num_boxes(_persp); + } + + /* returns all selected boxes sharing this perspective */ + std::list selectedBoxes(Inkscape::Selection *sel); + + inline void updateBoxDisplays() const { + g_return_if_fail (_persp); + persp3d_update_box_displays(_persp); + } + inline void updateBoxReprs() const { + g_return_if_fail (_persp); + persp3d_update_box_reprs(_persp); + } + inline void updatePerspRepr() const { + g_return_if_fail (_persp); + SP_OBJECT(_persp)->updateRepr(SP_OBJECT_WRITE_EXT); + } + inline void printPt() const { + g_return_if_fail (_persp); + persp3d_get_VP (_persp, _axis).print(""); + } + inline gchar const *axisString () { return Proj::string_from_axis(_axis); } + + unsigned int my_counter; + static unsigned int global_counter; // FIXME: Only to implement operator< so that we can merge lists. Do this in a better way!! +private: + Persp3D *_persp; + Proj::Axis _axis; }; +class VPDrag; -/** Given two axis directions out of {X, Y, Z}, returns the remaining one */ -inline Box3D::Axis third_axis_direction (Box3D::Axis dir1, Box3D::Axis dir2) { - return (Box3D::Axis) ((dir1 + dir2) ^ 0x7); -} - +struct less_ptr : public std::binary_function { + bool operator()(VanishingPoint *vp1, VanishingPoint *vp2) { + return GPOINTER_TO_INT(vp1) < GPOINTER_TO_INT(vp2); + } +}; -// FIXME: Store the Axis of the VP inside the class -class VanishingPoint : public NR::Point { +struct VPDragger { public: - inline VanishingPoint() : NR::Point() {}; - /*** - inline VanishingPoint(NR::Point const &pt, NR::Point const &ref = NR::Point(0,0)) - : NR::Point (pt), - ref_pt (ref), - v_dir (pt[NR::X] - ref[NR::X], pt[NR::Y] - ref[NR::Y]) {} - inline VanishingPoint(NR::Coord x, NR::Coord y, NR::Point const &ref = NR::Point(0,0)) - : NR::Point (x, y), - ref_pt (ref), - v_dir (x - ref[NR::X], y - ref[NR::Y]) {} - ***/ - VanishingPoint(NR::Point const &pt, NR::Point const &inf_dir, VPState st); - VanishingPoint(NR::Point const &pt); - VanishingPoint(NR::Point const &dir, VPState const state); - VanishingPoint(NR::Point const &pt, NR::Point const &direction); - VanishingPoint(NR::Coord x, NR::Coord y); - VanishingPoint(NR::Coord x, NR::Coord y, VPState const state); - VanishingPoint(NR::Coord x, NR::Coord y, NR::Coord dir_x, NR::Coord dir_y); - VanishingPoint(VanishingPoint const &rhs); - - bool is_finite(); - VPState toggle_parallel(); - void draw(Box3D::Axis const axis); // Draws a point on the canvas if state == VP_FINITE - //inline VPState state() { return state; } - - VPState state; - //NR::Point ref_pt; // point of reference to compute the direction of parallel lines - NR::Point v_dir; // direction of perslective lines if the VP has state == VP_INFINITE + VPDragger(VPDrag *parent, Geom::Point p, VanishingPoint &vp); + ~VPDragger(); -private: + VPDrag *parent; + SPKnot *knot; + + // position of the knot, desktop coords + Geom::Point point; + // position of the knot before it began to drag; updated when released + Geom::Point point_original; + + bool dragging_started; + + std::list vps; + + void addVP(VanishingPoint &vp, bool update_pos = false); + void removeVP(const VanishingPoint &vp); + + void updateTip(); + + guint numberOfBoxes(); // the number of boxes linked to all VPs of the dragger + VanishingPoint *findVPWithBox(SPBox3D *box); + std::set VPsOfSelectedBoxes(); + + bool hasPerspective(const Persp3D *persp); + void mergePerspectives(); // remove duplicate perspectives + + void updateBoxDisplays(); + void updateVPs(Geom::Point const &pt); + void updateZOrders(); + + void printVPs(); }; +struct VPDrag { +public: + VPDrag(SPDocument *document); + ~VPDrag(); -} // namespace Box3D + VPDragger *getDraggerFor (VanishingPoint const &vp); + + bool dragging; + + SPDocument *document; + GList *draggers; + GSList *lines; + + void printDraggers(); // convenience for debugging + /* + * FIXME: Should the following functions be merged? + * Also, they should make use of the info in a VanishingPoint structure (regarding boxes + * and perspectives) rather than each time iterating over the whole list of selected items? + */ + void updateDraggers (); + void updateLines (); + void updateBoxHandles (); + void updateBoxReprs (); + void updateBoxDisplays (); + void drawLinesForFace (const SPBox3D *box, Proj::Axis axis); //, guint corner1, guint corner2, guint corner3, guint corner4); + bool show_lines; /* whether perspective lines are drawn at all */ + guint front_or_rear_lines; /* whether we draw perspective lines from all corners or only the + front/rear corners (indicated by the first/second bit, respectively */ + + + inline bool hasEmptySelection() { return this->selection->isEmpty(); } + bool allBoxesAreSelected (VPDragger *dragger); + GSList * selectedBoxesWithVPinDragger (VPDragger *dragger); + // FIXME: Should this be private? (It's the case with the corresponding function in gradient-drag.h) + // But vp_knot_grabbed_handler + void addDragger (VanishingPoint &vp); -/** A function to print out the VanishingPoint (prints the coordinates) **/ -/*** -inline std::ostream &operator<< (std::ostream &out_file, const VanishingPoint &vp) { - out_file << vp; - return out_file; -} -***/ + void swap_perspectives_of_VPs(Persp3D *persp2, Persp3D *persp1); + +private: + //void deselect_all(); + + void addLine (Geom::Point p1, Geom::Point p2, guint32 rgba); + + Inkscape::Selection *selection; + sigc::connection sel_changed_connection; + sigc::connection sel_modified_connection; +}; + +} // namespace Box3D #endif /* !SEEN_VANISHING_POINT_H */