summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: fcb73bd)
raw | patch | inline | side by side (parent: fcb73bd)
author | cilix42 <cilix42@users.sourceforge.net> | |
Mon, 6 Aug 2007 06:51:01 +0000 (06:51 +0000) | ||
committer | cilix42 <cilix42@users.sourceforge.net> | |
Mon, 6 Aug 2007 06:51:01 +0000 (06:51 +0000) |
13 files changed:
diff --git a/src/attributes.cpp b/src/attributes.cpp
index ee7ebff69fb23108a22f4266e2642daae577cdde..90f3e0280ee63df8adccc1b5a8c88d92aeba5676 100644 (file)
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
{SP_ATTR_INKSCAPE_3DBOX_CORNER_A, "inkscape:box3dcornerA"}, // "upper left front" corner
{SP_ATTR_INKSCAPE_3DBOX_CORNER_B, "inkscape:box3dcornerB"}, // "lower right front" corner
{SP_ATTR_INKSCAPE_3DBOX_CORNER_C, "inkscape:box3dcornerC"}, // "lower right rear" corner
+ {SP_ATTR_INKSCAPE_3DBOX_PERSPECTIVE, "inkscape:perspective"},
/* SPEllipse */
{SP_ATTR_R, "r"},
{SP_ATTR_CX, "cx"},
diff --git a/src/attributes.h b/src/attributes.h
index 5eb906320bec59993dc42259c0e3abc19f458c92..9a969dc8cbdde73f7577bba1edf0a878597f60ba 100644 (file)
--- a/src/attributes.h
+++ b/src/attributes.h
SP_ATTR_INKSCAPE_3DBOX_CORNER_A, // "upper left front" corner
SP_ATTR_INKSCAPE_3DBOX_CORNER_B, // "lower right front" corner
SP_ATTR_INKSCAPE_3DBOX_CORNER_C, // "lower right rear" corner
+ SP_ATTR_INKSCAPE_3DBOX_PERSPECTIVE,
/* SPEllipse */
SP_ATTR_R,
SP_ATTR_CX,
diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp
index fc4e7462934f66914201db5e7c3a649f842b7860..c82728c9760131f0f4826609aa96d27baefe3b32 100644 (file)
--- a/src/box3d-context.cpp
+++ b/src/box3d-context.cpp
desktop = SP_EVENT_CONTEXT_DESKTOP(bc);
SP_OBJECT(bc->item)->updateRepr();
+ sp_3dbox_set_ratios(SP_3DBOX(bc->item));
sp_canvas_end_forced_full_redraws(desktop->canvas);
diff --git a/src/box3d.cpp b/src/box3d.cpp
index 76dad605b9f5fa60f5284d45493cec954aa92305..44b2c9bbef9ab2ec697da06dbee636f83ed3e56d 100644 (file)
--- a/src/box3d.cpp
+++ b/src/box3d.cpp
@@ -32,11 +32,13 @@ static Inkscape::XML::Node *sp_3dbox_write(SPObject *object, Inkscape::XML::Node
static gchar *sp_3dbox_description(SPItem *item);
//static void sp_3dbox_set_shape(SPShape *shape);
-static void sp_3dbox_set_shape(SP3DBox *box3d);
+//static void sp_3dbox_set_shape(SP3DBox *box3d);
static void sp_3dbox_update_corner_with_value_from_svg (SPObject *object, guint corner_id, const gchar *value);
+static void sp_3dbox_update_perspective (Box3D::Perspective3D *persp, const gchar *value);
static gchar * sp_3dbox_get_corner_coords_string (SP3DBox *box, guint id);
static std::pair<gdouble, gdouble> sp_3dbox_get_coord_pair_from_string (const gchar *);
+static gchar * sp_3dbox_get_perspective_string (SP3DBox *box);
static SPGroupClass *parent_class;
SP3DBox *box = SP_3DBOX (object);
- Box3D::Perspective3D::current_perspective->add_box (box);
+ if (repr->attribute ("inkscape:perspective") == NULL) {
+ // we are creating a new box; link it to the current perspective
+ Box3D::Perspective3D::current_perspective->add_box (box);
+ } else {
+ // create a new perspective that we can compare with existing ones
+ Box3D::Perspective3D *persp = new Box3D::Perspective3D (Box3D::VanishingPoint (0,0),
+ Box3D::VanishingPoint (0,0),
+ Box3D::VanishingPoint (0,0));
+ sp_3dbox_update_perspective (persp, repr->attribute ("inkscape:perspective"));
+ SPDesktop *desktop = inkscape_active_desktop();
+ Box3D::Perspective3D *comp = desktop->find_perspective (persp);
+ if (comp == NULL) {
+ // perspective doesn't exist yet
+ desktop->add_perspective (persp);
+ persp->add_box (box);
+ } else {
+ // link the box to the existing perspective and delete the temporary one
+ comp->add_box (box);
+ delete persp;
+ //g_assert (Box3D::get_persp_of_box (box) == comp);
+
+ // FIXME: If the paths of the box's faces do not correspond to the svg representation of the perspective
+ // the box is shown with a "wrong" initial shape that is only corrected after dragging.
+ // Should we "repair" this by updating the paths at the end of sp_3dbox_build()?
+ // Maybe it would be better to simply destroy and rebuild them in sp_3dbox_link_to_existing_paths().
+ }
+ }
sp_object_read_attr(object, "inkscape:box3dcornerA");
sp_object_read_attr(object, "inkscape:box3dcornerB");
@@ -127,6 +155,8 @@ sp_3dbox_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr
// Check whether the paths of the faces of the box need to be linked to existing paths in the
// document (e.g., after a 'redo' operation or after opening a file) and do so if necessary.
sp_3dbox_link_to_existing_paths (box, repr);
+
+ sp_3dbox_set_ratios (box);
}
static void
@@ -160,6 +190,9 @@ static void sp_3dbox_set(SPObject *object, unsigned int key, const gchar *value)
case SP_ATTR_INKSCAPE_3DBOX_CORNER_C:
sp_3dbox_update_corner_with_value_from_svg (object, 5, value);
break;
+ case SP_ATTR_INKSCAPE_3DBOX_PERSPECTIVE:
+ sp_3dbox_update_perspective (Box3D::get_persp_of_box (SP_3DBOX (object)), value);
+ break;
default:
if (((SPObjectClass *) (parent_class))->set) {
((SPObjectClass *) (parent_class))->set(object, key, value);
@@ -206,17 +239,21 @@ static Inkscape::XML::Node *sp_3dbox_write(SPObject *object, Inkscape::XML::Node
}
if (flags & SP_OBJECT_WRITE_EXT) {
- gchar *coords;
- coords = sp_3dbox_get_corner_coords_string (box, 2);
- repr->setAttribute("inkscape:box3dcornerA", coords);
+ gchar *str;
+ str = sp_3dbox_get_corner_coords_string (box, 2);
+ repr->setAttribute("inkscape:box3dcornerA", str);
+
+ str = sp_3dbox_get_corner_coords_string (box, 1);
+ repr->setAttribute("inkscape:box3dcornerB", str);
- coords = sp_3dbox_get_corner_coords_string (box, 1);
- repr->setAttribute("inkscape:box3dcornerB", coords);
+ str = sp_3dbox_get_corner_coords_string (box, 5);
+ repr->setAttribute("inkscape:box3dcornerC", str);
- coords = sp_3dbox_get_corner_coords_string (box, 5);
- repr->setAttribute("inkscape:box3dcornerC", coords);
+ str = sp_3dbox_get_perspective_string (box);
+ repr->setAttribute("inkscape:perspective", str);
+ sp_3dbox_set_ratios (box);
- g_free ((void *) coords);
+ g_free ((void *) str);
}
if (((SPObjectClass *) (parent_class))->write) {
return g_strdup(_("<b>3D Box</b>"));
}
+void sp_3dbox_set_ratios (SP3DBox *box, Box3D::Axis axes)
+{
+ Box3D::Perspective3D *persp = Box3D::get_persp_of_box (box);
+ NR::Point pt;
+
+ if (axes & Box3D::X) {
+ pt = persp->get_vanishing_point (Box3D::X)->get_pos();
+ box->ratio_x = NR::L2 (pt - box->corners[2]) / NR::L2 (pt - box->corners[3]);
+ }
+
+ if (axes & Box3D::Y) {
+ pt = persp->get_vanishing_point (Box3D::Y)->get_pos();
+ box->ratio_y = NR::L2 (pt - box->corners[2]) / NR::L2 (pt - box->corners[0]);
+ }
+
+ if (axes & Box3D::Z) {
+ pt = persp->get_vanishing_point (Box3D::Z)->get_pos();
+ box->ratio_z = NR::L2 (pt - box->corners[4]) / NR::L2 (pt - box->corners[0]);
+ }
+}
+
void
sp_3dbox_position_set (SP3DBoxContext &bc)
{
***/
}
-static void
+//static
+void
// FIXME: Note that this is _not_ the virtual set_shape() method inherited from SPShape,
// since SP3DBox is inherited from SPGroup. The following method is "artificially"
// called from sp_3dbox_update().
//sp_3dbox_set_shape(SPShape *shape)
-sp_3dbox_set_shape(SP3DBox *box3d)
+sp_3dbox_set_shape(SP3DBox *box3d, bool use_previous_corners)
{
// FIXME: How to handle other contexts???
// FIXME: Is tools_isactive(..) more recommended to check for the current context/tool?
/* Only update the curves during dragging; setting the svg representations
is expensive and only done once at the end */
- sp_3dbox_recompute_corners (box3d, bc->drag_origin, bc->drag_ptB, bc->drag_ptC);
+ if (!use_previous_corners) {
+ sp_3dbox_recompute_corners (box3d, bc->drag_origin, bc->drag_ptB, bc->drag_ptC);
+ } else {
+ sp_3dbox_recompute_corners (box3d, box3d->corners[2], box3d->corners[1], box3d->corners[5]);
+ }
if (bc->extruded) {
box3d->faces[0]->set_corners (box3d->corners[0], box3d->corners[4], box3d->corners[6], box3d->corners[2]);
box3d->faces[1]->set_corners (box3d->corners[1], box3d->corners[5], box3d->corners[7], box3d->corners[3]);
return std::make_pair(coord1, coord2);
}
-// auxiliary function
+static gchar *
+sp_3dbox_get_perspective_string (SP3DBox *box)
+{
+
+ return sp_3dbox_get_svg_descr_of_persp (Box3D::get_persp_of_box (box));
+}
+
+gchar *
+sp_3dbox_get_svg_descr_of_persp (Box3D::Perspective3D *persp)
+{
+ // FIXME: We should move this code to perspective3d.cpp, but this yields compiler errors. Why?
+ Inkscape::SVGOStringStream os;
+
+ Box3D::VanishingPoint vp = *(persp->get_vanishing_point (Box3D::X));
+ os << vp[NR::X] << "," << vp[NR::Y] << ",";
+ os << vp.v_dir[NR::X] << "," << vp.v_dir[NR::Y] << ",";
+ if (vp.is_finite()) {
+ os << "finite,";
+ } else {
+ os << "infinite,";
+ }
+
+ vp = *(persp->get_vanishing_point (Box3D::Y));
+ os << vp[NR::X] << "," << vp[NR::Y] << ",";
+ os << vp.v_dir[NR::X] << "," << vp.v_dir[NR::Y] << ",";
+ if (vp.is_finite()) {
+ os << "finite,";
+ } else {
+ os << "infinite,";
+ }
+
+ vp = *(persp->get_vanishing_point (Box3D::Z));
+ os << vp[NR::X] << "," << vp[NR::Y] << ",";
+ os << vp.v_dir[NR::X] << "," << vp.v_dir[NR::Y] << ",";
+ if (vp.is_finite()) {
+ os << "finite";
+ } else {
+ os << "infinite";
+ }
+
+ return g_strdup(os.str().c_str());
+}
+
+// auxiliary functions
static void
sp_3dbox_update_corner_with_value_from_svg (SPObject *object, guint corner_id, const gchar *value)
{
@@ -470,6 +576,36 @@ sp_3dbox_update_corner_with_value_from_svg (SPObject *object, guint corner_id, c
object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
+static void
+sp_3dbox_update_perspective (Box3D::Perspective3D *persp, const gchar *value)
+{
+ // WARNING! This function changes the perspective associated to 'box'. Since there may be
+ // many other boxes linked to the same perspective, their perspective is also changed.
+ // If this behaviour is not desired in all cases, we need a different function.
+ if (value == NULL) return;
+
+ gchar **vps = g_strsplit( value, ",", 0);
+ for (int i = 0; i < 15; ++i) {
+ if (vps[i] == NULL) {
+ g_warning ("Malformed svg attribute 'perspective'\n");
+ return;
+ }
+ }
+
+ persp->set_vanishing_point (Box3D::X, g_ascii_strtod (vps[0], NULL), g_ascii_strtod (vps[1], NULL),
+ g_ascii_strtod (vps[2], NULL), g_ascii_strtod (vps[3], NULL),
+ Box3D::VP_FINITE);
+ persp->set_vanishing_point (Box3D::Y, g_ascii_strtod (vps[5], NULL), g_ascii_strtod (vps[6], NULL),
+ g_ascii_strtod (vps[7], NULL), g_ascii_strtod (vps[8], NULL),
+ Box3D::VP_FINITE);
+ persp->set_vanishing_point (Box3D::Z, g_ascii_strtod (vps[10], NULL), g_ascii_strtod (vps[11], NULL),
+ g_ascii_strtod (vps[12], NULL), g_ascii_strtod (vps[13], NULL),
+ Box3D::VP_FINITE);
+
+ // update the other boxes linked to the same perspective
+ persp->reshape_boxes (Box3D::XYZ);
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/box3d.h b/src/box3d.h
index ee0f30c8169c7c5375595337bcf6926758285d13..1b40afa760ea79de7f53296879ee9ca928a17806 100644 (file)
--- a/src/box3d.h
+++ b/src/box3d.h
struct SP3DBox : public SPGroup {
NR::Point corners[8];
Box3DFace *faces[6];
+
+ // TODO: Keeping/updating the ratios works reasonably well but is still an ad hoc implementation.
+ // Use a mathematically correct model to update the boxes.
+ double ratio_x;
+ double ratio_y;
+ double ratio_z;
};
struct SP3DBoxClass {
GType sp_3dbox_get_type (void);
void sp_3dbox_position_set (SP3DBoxContext &bc);
+void sp_3dbox_set_shape(SP3DBox *box3d, bool use_previous_corners = false);
void sp_3dbox_recompute_corners (SP3DBox *box, NR::Point const pt1, NR::Point const pt2, NR::Point const pt3);
void sp_3dbox_update_curves (SP3DBox *box);
void sp_3dbox_link_to_existing_paths (SP3DBox *box, Inkscape::XML::Node *repr);
+void sp_3dbox_set_ratios (SP3DBox *box, Box3D::Axis axes = Box3D::XYZ);
void sp_3dbox_move_corner_in_XY_plane (SP3DBox *box, guint id, NR::Point pt, Box3D::Axis axes = Box3D::XY);
void sp_3dbox_move_corner_in_Z_direction (SP3DBox *box, guint id, NR::Point pt, bool constrained = true);
NR::Maybe<NR::Point> sp_3dbox_get_center (SP3DBox *box);
NR::Maybe<NR::Point> sp_3dbox_get_midpoint_between_corners (SP3DBox *box, guint id_corner1, guint id_corner2);
+gchar * sp_3dbox_get_svg_descr_of_persp (Box3D::Perspective3D *persp);
+
inline NR::Point sp_3dbox_get_corner (SP3DBox *box, guint id) { return box->corners[id]; }
inline bool sp_3dbox_corners_are_adjacent (guint id_corner1, guint id_corner2) {
return Box3D::is_single_axis_direction ((Box3D::Axis) (id_corner1 ^ id_corner2));
diff --git a/src/desktop.cpp b/src/desktop.cpp
index 6314621c14e146805075c28fae13c2d916a893df..f58864955d01641cbc2c4bbf52c27592349caa09 100644 (file)
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
void
SPDesktop::add_perspective (Box3D::Perspective3D * const persp)
{
+ // check that the perspective is not yet linked to another desktop
+ if (persp->desktop != NULL) {
+ g_assert (persp->desktop == this);
+ }
+
// FIXME: Should we handle the case that the perspectives have equal VPs but are not identical?
+ // If so, we need to take care of relinking the boxes, etc.
if (persp == NULL || g_slist_find (this->perspectives, persp)) return;
this->perspectives = g_slist_prepend (this->perspectives, persp);
persp->desktop = this;
void SPDesktop::remove_perspective (Box3D::Perspective3D * const persp)
{
if (persp == NULL) return;
-
if (!g_slist_find (this->perspectives, persp)) {
g_warning ("Could not find perspective in current desktop. Not removed.\n");
return;
}
-
this->perspectives = g_slist_remove (this->perspectives, persp);
}
+// find an existing perspective whose VPs are equal to those of persp
+Box3D::Perspective3D * SPDesktop::find_perspective (Box3D::Perspective3D * const persp)
+{
+ for (GSList *p = this->perspectives; p != NULL; p = p->next) {
+ if (*((Box3D::Perspective3D *) p->data) == *persp) {
+ return ((Box3D::Perspective3D *) p->data);
+ }
+ }
+ return NULL; // perspective was not found
+}
+
/**
* Return viewbox dimensions.
*/
diff --git a/src/desktop.h b/src/desktop.h
index fa6602651bc1b8c8dd2b8fc4ade2a99146e7fe22..5f4e2cfab63a110d31fd5518da44fb91dd5642d7 100644 (file)
--- a/src/desktop.h
+++ b/src/desktop.h
// Methods to handle 3D perspective
void add_perspective (Box3D::Perspective3D * const persp);
void remove_perspective (Box3D::Perspective3D * const persp);
+ Box3D::Perspective3D * find_perspective (Box3D::Perspective3D * const persp); // find an existing perspective whose VPs are equal to those of persp
NR::Rect get_display_area() const;
void set_display_area (double x0, double y0, double x1, double y1, double border, bool log = true);
diff --git a/src/knotholder.cpp b/src/knotholder.cpp
index a24bb16259d0bcf2b70d7459e0f9436e67448810..d8776cca7219db5a91f417fbdd32f7c55bd28c9d 100644 (file)
--- a/src/knotholder.cpp
+++ b/src/knotholder.cpp
* \param p In desktop coordinates.
*/
-static void knotholder_update_knots(SPKnotHolder *knot_holder, SPItem *item)
+//static
+void knotholder_update_knots(SPKnotHolder *knot_holder, SPItem *item)
{
NR::Matrix const i2d(sp_item_i2d_affine(item));
diff --git a/src/knotholder.h b/src/knotholder.h
index 971dae3b0747a2036ebe338ea6d32ef74bb47957..18b6c4165241b38fa6de694a62a238bb2d95f871 100644 (file)
--- a/src/knotholder.h
+++ b/src/knotholder.h
GType sp_knot_holder_get_type();
+// For testing. What is the right way to update the knots from Perspective3D::reshape_boxes() ?
+void knotholder_update_knots(SPKnotHolder *knot_holder, SPItem *item);
+
#define SP_TYPE_KNOT_HOLDER (sp_knot_holder_get_type())
#endif /* !__SP_KNOTHOLDER_H__ */
diff --git a/src/perspective3d.cpp b/src/perspective3d.cpp
index 27366e564203e9134009adad5c7a40ed852861ec..d4990fd397b5b99ad9d8c5b901dfd0b15c2e943e 100644 (file)
--- a/src/perspective3d.cpp
+++ b/src/perspective3d.cpp
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#include "box3d.h"
#include "box3d-context.h"
#include "perspective-line.h"
#include <iostream>
// can probably be removed later
#include "inkscape.h"
+#include "knotholder.h"
namespace Box3D {
Perspective3D::~Perspective3D ()
{
- g_assert (desktop != NULL);
- desktop->remove_perspective (this);
+ // we can have desktop == NULL when building a box whose attribute "inkscape:perspective" is set
+ if (desktop != NULL) {
+ desktop->remove_perspective (this);
+ }
delete vp_x;
delete vp_y;
g_slist_free (boxes);
}
+bool
+Perspective3D::operator==(Perspective3D const &other)
+{
+ // 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);
+}
VanishingPoint *
Perspective3D::get_vanishing_point (Box3D::Axis const dir)
@@ -134,6 +144,30 @@ Perspective3D::set_vanishing_point (Box3D::Axis const dir, VanishingPoint const
}
}
+void
+Perspective3D::set_vanishing_point (Box3D::Axis const dir, gdouble pt_x, gdouble pt_y, gdouble dir_x, gdouble dir_y, VPState st)
+{
+ VanishingPoint *vp;
+ switch (dir) {
+ case X:
+ vp = vp_x;
+ break;
+ case Y:
+ vp = vp_y;
+ break;
+ case Z:
+ vp = vp_z;
+ break;
+ case NONE:
+ // no vanishing point to set
+ return;
+ }
+
+ vp->set_pos (pt_x, pt_y);
+ vp->v_dir = NR::Point (dir_x, dir_y);
+ vp->state = st;
+}
+
void
Perspective3D::add_box (SP3DBox *box)
{
return (g_slist_find (this->boxes, box) != NULL);
}
+/**
+ * Update the shape of a box after a handle was dragged or a VP was changed, according to the stored ratios.
+ */
+void
+Perspective3D::reshape_boxes (Box3D::Axis axes)
+{
+ // TODO: Leave the "correct" corner fixed according to which face is supposed to be on front.
+ NR::Point new_pt;
+ VanishingPoint *vp;
+ for (const GSList *i = this->boxes; i != NULL; i = i->next) {
+ SP3DBox *box = SP_3DBOX (i->data);
+ if (axes & Box3D::X) {
+ vp = this->get_vanishing_point (Box3D::X);
+ new_pt = vp->get_pos() + box->ratio_x * (box->corners[3] - vp->get_pos());
+ sp_3dbox_move_corner_in_XY_plane (box, 2, new_pt);
+ }
+ if (axes & Box3D::Y) {
+ vp = this->get_vanishing_point (Box3D::Y);
+ new_pt = vp->get_pos() + box->ratio_y * (box->corners[0] - vp->get_pos());
+ sp_3dbox_move_corner_in_XY_plane (box, 2, new_pt);
+ }
+ if (axes & Box3D::Z) {
+ vp = this->get_vanishing_point (Box3D::Z);
+ new_pt = vp->get_pos() + box->ratio_z * (box->corners[0] - vp->get_pos());
+ sp_3dbox_move_corner_in_Z_direction (box, 4, new_pt);
+ }
+
+ sp_3dbox_set_shape (box, true);
+ // FIXME: Is there a way update the knots without accessing the
+ // statically linked function knotholder_update_knots?
+ SPEventContext *ec = inkscape_active_event_context();
+ g_assert (ec != NULL);
+ if (ec->shape_knot_holder != NULL) {
+ knotholder_update_knots(ec->shape_knot_holder, (SPItem *) box);
+ }
+ }
+}
+
+void
+Perspective3D::update_box_reprs ()
+{
+ for (GSList *i = this->boxes; i != NULL; i = i->next) {
+ SP_OBJECT(SP_3DBOX (i->data))->updateRepr(SP_OBJECT_WRITE_EXT);
+ }
+}
+
+// FIXME: We get compiler errors when we try to move the code from sp_3dbox_get_perspective_string to this function
+/***
+gchar *
+Perspective3D::svg_string ()
+{
+}
+***/
+
} // namespace Box3D
/*
diff --git a/src/perspective3d.h b/src/perspective3d.h
index afecb2e48b88489d479b5ed35fc5c6fe8f3bc543..2cffd3419cbd0c20d2295f30a84f0bd353423e6e 100644 (file)
--- a/src/perspective3d.h
+++ b/src/perspective3d.h
#define SEEN_PERSPECTIVE3D_H
#include "vanishing-point.h"
+#include "svg/stringstream.h"
class SP3DBox;
Perspective3D(Perspective3D &other);
~Perspective3D();
+ bool operator== (Perspective3D const &other);
+
VanishingPoint *get_vanishing_point (Box3D::Axis const dir);
void set_vanishing_point (Box3D::Axis const dir, VanishingPoint const &pt);
+ void set_vanishing_point (Box3D::Axis const dir, gdouble pt_x, gdouble pt_y, gdouble dir_x, gdouble dir_y, VPState st);
void add_box (SP3DBox *box);
void remove_box (const SP3DBox *box);
bool has_box (const SP3DBox *box);
+ void reshape_boxes (Box3D::Axis axes);
+ void update_box_reprs ();
static Perspective3D * current_perspective; // should current_perspective be moved to desktop.h?
index 20c67cb28d1d9c37956be9b7000ac5093699afe6..5f40936cf5ca637da07e98c252eb15b223274a43 100644 (file)
--- a/src/vanishing-point.cpp
+++ b/src/vanishing-point.cpp
this->v_dir = rhs.v_dir;
}
+bool VanishingPoint::operator== (VanishingPoint const &other)
+{
+ // Should we compare the parent perspectives, too? Probably not.
+ if ((*this)[NR::X] == other[NR::X] && (*this)[NR::Y] == other[NR::Y]
+ && this->state == other.state && this->v_dir == other.v_dir) {
+ return true;
+ }
+ return false;
+}
bool VanishingPoint::is_finite() const
{
diff --git a/src/vanishing-point.h b/src/vanishing-point.h
index 85b7434e2dc6be07b1ff7712ac880c43fa44836b..918b27fc76876c79bc20bec4507af2d2d18c0b92 100644 (file)
--- a/src/vanishing-point.h
+++ b/src/vanishing-point.h
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