X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fvanishing-point.h;h=aef5f6f5c4370d874c82dec2ffad2feb8fe95eba;hb=9e973c4fb2183b877bb600a7e9c75e93b3e7d6d1;hp=918b27fc76876c79bc20bec4507af2d2d18c0b92;hpb=b2dfb5760b4ff97eabdaa0272ba7ed7f0dd8c6eb;p=inkscape.git diff --git a/src/vanishing-point.h b/src/vanishing-point.h index 918b27fc7..aef5f6f5c 100644 --- a/src/vanishing-point.h +++ b/src/vanishing-point.h @@ -12,10 +12,17 @@ #ifndef SEEN_VANISHING_POINT_H #define SEEN_VANISHING_POINT_H +#include #include "libnr/nr-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" -#include "line-geometry.h" // TODO: Remove this include as soon as we don't need create_canvas_(point|line) any more. +class SPBox3D; namespace Box3D { @@ -24,60 +31,182 @@ enum VPState { VP_INFINITE // perspective lines are parallel }; -// FIXME: Store the Axis of the VP inside the class -class VanishingPoint : public NR::Point { +/* 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: - 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 operator== (VanishingPoint const &other); - - inline NR::Point get_pos() const { return NR::Point ((*this)[NR::X], (*this)[NR::Y]); } - inline void set_pos(NR::Point const &pt) { (*this)[NR::X] = pt[NR::X]; - (*this)[NR::Y] = pt[NR::Y]; } - inline void set_pos(const double pt_x, const double pt_y) { (*this)[NR::X] = pt_x; - (*this)[NR::Y] = pt_y; } - - bool is_finite() const; - 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 - + 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 NR::Point get_pos() const { + g_return_val_if_fail (_persp, NR::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; + +struct less_ptr : public std::binary_function { + bool operator()(VanishingPoint *vp1, VanishingPoint *vp2) { + return GPOINTER_TO_INT(vp1) < GPOINTER_TO_INT(vp2); + } +}; + +struct VPDragger { +public: + VPDragger(VPDrag *parent, NR::Point p, VanishingPoint &vp); + ~VPDragger(); + + VPDrag *parent; + SPKnot *knot; + + // position of the knot, desktop coords + NR::Point point; + // position of the knot before it began to drag; updated when released + NR::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(NR::Point const &pt); + void updateZOrders(); + + void printVPs(); +}; + +struct VPDrag { +public: + VPDrag(SPDocument *document); + ~VPDrag(); + + 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 */ -} // namespace Box3D + inline bool hasEmptySelection() { return this->selection->isEmpty(); } + bool allBoxesAreSelected (VPDragger *dragger); + GSList * selectedBoxesWithVPinDragger (VPDragger *dragger); -/** 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; -} -***/ + // 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); + + void swap_perspectives_of_VPs(Persp3D *persp2, Persp3D *persp1); + +private: + //void deselect_all(); + + void addLine (NR::Point p1, NR::Point p2, guint32 rgba); + + Inkscape::Selection *selection; + sigc::connection sel_changed_connection; + sigc::connection sel_modified_connection; +}; + +} // namespace Box3D #endif /* !SEEN_VANISHING_POINT_H */