summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMaximilian Albert <maximilian.albert@gmail.com>2007-07-03 18:55:50 +0000
committercilix42 <cilix42@users.sourceforge.net>2007-07-03 18:55:50 +0000
commit8085b4cf30b6b8bdc6fb331a0ced400f468f6de7 (patch)
tree9491d78f25a5dde96cf29c7417dace81915d3950 /src
parentMore meaningful name for 3D axis directions (diff)
downloadinkscape-8085b4cf30b6b8bdc6fb331a0ced400f468f6de7.tar.gz
inkscape-8085b4cf30b6b8bdc6fb331a0ced400f468f6de7.zip
Only create the faces of a 3D box when needed (use pointers to refer to them).
(bzr r3170)
Diffstat (limited to 'src')
-rw-r--r--src/box3d-context.cpp24
-rw-r--r--src/box3d-face.cpp45
-rw-r--r--src/box3d-face.h1
-rw-r--r--src/box3d.cpp60
-rw-r--r--src/box3d.h2
5 files changed, 105 insertions, 27 deletions
diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp
index 35bdb6af2..1ec86b827 100644
--- a/src/box3d-context.cpp
+++ b/src/box3d-context.cpp
@@ -357,8 +357,18 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven
rc->ctrl_dragged = event->motion.state & GDK_CONTROL_MASK;
- if (event->motion.state & GDK_SHIFT_MASK)
- rc->extruded = true; // set rc->extruded once shift is pressed
+ if (event->motion.state & GDK_SHIFT_MASK && !rc->extruded) {
+ /* once shift is pressed, set rc->extruded and create the remaining faces */
+ rc->extruded = true;
+
+ /* The separate faces */
+ SP3DBox *box3d = SP_3DBOX(rc->item);
+ for (int i = 0; i < 6; ++i) {
+ if (i == 4 || box3d->faces[i]) continue;
+ box3d->faces[i] = new Box3DFace (box3d);
+ box3d->faces[i]->hook_path_to_3dbox();
+ }
+ }
if (!rc->extruded) {
rc->drag_ptB = motion_dt;
@@ -522,14 +532,8 @@ static void sp_3dbox_drag(SP3DBoxContext &rc, guint state)
Inkscape::GC::release(repr);
rc.item->transform = SP_ITEM(desktop->currentRoot())->getRelativeTransform(desktop->currentLayer());
- /* The separate faces (created from rear to front) */
- SP3DBox *box3d = SP_3DBOX(rc.item);
- box3d->faces[2].hook_path_to_3dbox();
- box3d->faces[3].hook_path_to_3dbox();
- box3d->faces[4].hook_path_to_3dbox();
- box3d->faces[5].hook_path_to_3dbox();
- box3d->faces[0].hook_path_to_3dbox();
- box3d->faces[1].hook_path_to_3dbox();
+ /* Hook path to the only currenctly existing face */
+ SP_3DBOX(rc.item)->faces[4]->hook_path_to_3dbox();
rc.item->updateRepr();
diff --git a/src/box3d-face.cpp b/src/box3d-face.cpp
index d038de84f..e499fe4d0 100644
--- a/src/box3d-face.cpp
+++ b/src/box3d-face.cpp
@@ -78,6 +78,45 @@ Box3DFace::Box3DFace(Box3DFace const &box3dface)
this->dir2 = box3dface.dir2;
}
+/**
+ * Construct a 3D box face with opposite corners A and C whose sides are directed
+ * along axis1 and axis2. The corners have the following order:
+ *
+ * A = corners[0] --> along axis1 --> B = corners[1] --> along axis2 --> C = corners[2]
+ * --> along axis1 --> D = corners[3] --> along axis2 --> D = corners[0].
+ *
+ * Note that several other functions rely on this precise order.
+ */
+void
+Box3DFace::set_face (NR::Point const A, NR::Point const C, Box3D::Axis const axis1, Box3D::Axis const axis2)
+{
+ corners[0] = A;
+ corners[2] = C;
+ if (!SP_IS_3DBOX_CONTEXT(inkscape_active_event_context()))
+ return;
+ SP3DBoxContext *bc = SP_3DBOX_CONTEXT(inkscape_active_event_context());
+
+ Box3D::PerspectiveLine line1 (A, axis1);
+ Box3D::PerspectiveLine line2 (C, axis2);
+ NR::Maybe<NR::Point> B = line1.intersect(line2);
+
+ Box3D::PerspectiveLine line3 (corners[0], axis2);
+ Box3D::PerspectiveLine line4 (corners[2], axis1);
+ NR::Maybe<NR::Point> D = line3.intersect(line4);
+
+ // FIXME: How to handle the case if one of the intersections doesn't exist?
+ // Maybe set them equal to the corresponding VPs?
+ if (!D) D = NR::Point(0.0, 0.0);
+ if (!B) B = NR::Point(0.0, 0.0);
+
+ corners[1] = *B;
+ corners[3] = *D;
+
+ this->dir1 = axis1;
+ this->dir2 = axis2;
+}
+
+
NR::Point Box3DFace::operator[](unsigned int i)
{
return corners[i % 4];
@@ -89,6 +128,8 @@ NR::Point Box3DFace::operator[](unsigned int i)
*/
void Box3DFace::hook_path_to_3dbox()
{
+ if (this->path) return; // This test can probably be removed.
+
SPDesktop *desktop = inkscape_active_desktop();
Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_EVENT_CONTEXT_DOCUMENT(inkscape_active_event_context()));
Inkscape::XML::Node *repr_face = xml_doc->createElement("svg:path");
@@ -110,6 +151,10 @@ void Box3DFace::set_curve()
SPDocument *doc = SP_OBJECT_DOCUMENT(this->parent_box3d);
gdouble height = sp_document_height(doc);
+ if (this->path == NULL) {
+ g_warning("this->path is NULL! \n");
+ return;
+ }
SPCurve *curve = sp_curve_new();
sp_curve_moveto(curve, corners[0][NR::X], height - corners[0][NR::Y]);
sp_curve_lineto(curve, corners[1][NR::X], height - corners[1][NR::Y]);
diff --git a/src/box3d-face.h b/src/box3d-face.h
index 1b1eb451e..e557aebf2 100644
--- a/src/box3d-face.h
+++ b/src/box3d-face.h
@@ -37,6 +37,7 @@ public:
Box3D::Axis const dir1, Box3D::Axis const dir2,
unsigned int shift_count = 0, NR::Maybe<NR::Point> pt_align = NR::Nothing(),
bool align_along_PL = false);
+ void set_face (NR::Point const A, NR::Point const C, Box3D::Axis const dir1, Box3D::Axis const dir2);
void hook_path_to_3dbox();
void set_path_repr();
diff --git a/src/box3d.cpp b/src/box3d.cpp
index 94dfaf996..290b5111e 100644
--- a/src/box3d.cpp
+++ b/src/box3d.cpp
@@ -21,6 +21,7 @@ static void sp_3dbox_class_init(SP3DBoxClass *klass);
static void sp_3dbox_init(SP3DBox *box3d);
static void sp_3dbox_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
+static void sp_shape_release (SPObject *object);
static void sp_3dbox_set(SPObject *object, unsigned int key, const gchar *value);
static void sp_3dbox_update(SPObject *object, SPCtx *ctx, guint flags);
static Inkscape::XML::Node *sp_3dbox_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
@@ -75,8 +76,12 @@ sp_3dbox_class_init(SP3DBoxClass *klass)
static void
sp_3dbox_init(SP3DBox *box3d)
{
+ if (box3d == NULL) { g_warning ("box3d is NULL!\n"); }
+ box3d->faces[4] = new Box3DFace (box3d);
+ //box3d->faces[4]->hook_path_to_3dbox();
for (int i = 0; i < 6; ++i) {
- box3d->faces[i] = Box3DFace (box3d);
+ if (i == 4) continue;
+ box3d->faces[i] = NULL;
}
}
@@ -90,6 +95,22 @@ sp_3dbox_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr
//sp_object_read_attr(object, "width");
}
+static void
+sp_3dbox_release (SPObject *object)
+{
+ SP3DBox *box3d = SP_3DBOX(object);
+ for (int i = 0; i < 6; ++i) {
+ if (box3d->faces[i]) {
+ delete box3d->faces[i]; // FIXME: Anything else to do? Do we need to clean up the face first?
+ }
+ }
+
+ if (((SPObjectClass *) parent_class)->release) {
+ ((SPObjectClass *) parent_class)->release (object);
+ }
+}
+
+
static void sp_3dbox_set(SPObject *object, unsigned int key, const gchar *value)
{
//SP3DBox *box3d = SP_3DBOX(object);
@@ -140,12 +161,13 @@ static Inkscape::XML::Node *sp_3dbox_write(SPObject *object, Inkscape::XML::Node
}
- box3d->faces[0].set_path_repr();
+ box3d->faces[4]->set_path_repr();
if (bc->extruded) {
NR::Point corner1, corner2, corner3, corner4;
sp_3dbox_compute_specific_corners (bc, corner1, corner2, corner3, corner4);
for (int i = 0; i < 6; ++i) {
- box3d->faces[i].set_path_repr();
+ if (i == 4) continue;
+ box3d->faces[i]->set_path_repr();
}
}
if (((SPObjectClass *) (parent_class))->write) {
@@ -199,20 +221,26 @@ sp_3dbox_set_shape(SP3DBox *box3d)
if (bc->extruded) {
sp_3dbox_compute_specific_corners (bc, corner1, corner2, corner3, corner4);
- box3d->faces[2].set_shape(bc->drag_origin, corner4, Box3D::Z, Box3D::Y);
- box3d->faces[2].set_curve();
- box3d->faces[3].set_shape(corner2, corner4, Box3D::X, Box3D::Y);
- box3d->faces[3].set_curve();
- box3d->faces[4].set_shape(bc->drag_origin, corner2, Box3D::X, Box3D::Z);
- box3d->faces[4].set_curve();
- box3d->faces[5].set_shape(bc->drag_ptB, corner4, Box3D::X, Box3D::Z);
- box3d->faces[5].set_curve();
-
- box3d->faces[1].set_shape(corner1, bc->drag_ptC, Box3D::Z, Box3D::Y);
- box3d->faces[1].set_curve();
+ for (int i=0; i < 6; ++i) {
+ if (!box3d->faces[i]) {
+ g_warning ("Face no. %d does not exist!\n", i);
+ return;
+ }
+ }
+ box3d->faces[0]->set_face (bc->drag_origin, corner4, Box3D::Z, Box3D::Y);
+ box3d->faces[0]->set_curve();
+ box3d->faces[5]->set_face (corner3, bc->drag_ptC, Box3D::Y, Box3D::X);
+ box3d->faces[5]->set_curve();
+ box3d->faces[3]->set_face (bc->drag_origin, corner2, Box3D::X, Box3D::Z);
+ box3d->faces[3]->set_curve();
+ box3d->faces[2]->set_face (bc->drag_ptB, corner4, Box3D::X, Box3D::Z);
+ box3d->faces[2]->set_curve();
+
+ box3d->faces[1]->set_face (corner1, bc->drag_ptC, Box3D::Z, Box3D::Y);
+ box3d->faces[1]->set_curve();
}
- box3d->faces[0].set_shape(bc->drag_origin, bc->drag_ptB, Box3D::X, Box3D::Y);
- box3d->faces[0].set_curve();
+ box3d->faces[4]->set_face(bc->drag_origin, bc->drag_ptB, Box3D::Y, Box3D::X);
+ box3d->faces[4]->set_curve();
}
diff --git a/src/box3d.h b/src/box3d.h
index 332848103..982596d8f 100644
--- a/src/box3d.h
+++ b/src/box3d.h
@@ -34,7 +34,7 @@
struct SP3DBox : public SPGroup {
- Box3DFace faces[6];
+ Box3DFace *faces[6];
};
struct SP3DBoxClass {