From 950183df6a75a3e57c1592cc2c8c5ce37f51afc2 Mon Sep 17 00:00:00 2001 From: cilix42 Date: Tue, 10 Jul 2007 13:58:55 +0000 Subject: [PATCH] Create all 3D box faces in the beginning (fixes resizing bug; first step towards correct handling of degenerate boxes) --- src/box3d-context.cpp | 18 +++++++----------- src/box3d-face.cpp | 27 ++++++++++++++++++--------- src/box3d-face.h | 9 +++------ src/box3d.cpp | 37 +++++++++++++++++++++++-------------- 4 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp index f9b2a1838..395623171 100644 --- a/src/box3d-context.cpp +++ b/src/box3d-context.cpp @@ -359,20 +359,14 @@ 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) { - /* once shift is pressed, set rc->extruded and create the remaining faces */ + /* once shift is pressed, set rc->extruded (no need to create further faces; + all of them are already created in sp_3dbox_init) */ 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; + rc->drag_ptC = motion_dt; } else { // Without Ctrl, motion of the extruded corner is constrained to the // perspective line from drag_ptB to vanishing point Y. @@ -535,8 +529,10 @@ static void sp_3dbox_drag(SP3DBoxContext &bc, guint state) Inkscape::GC::release(repr); bc.item->transform = SP_ITEM(desktop->currentRoot())->getRelativeTransform(desktop->currentLayer()); - /* Hook path to the only currenctly existing face */ - SP_3DBOX(bc.item)->faces[4]->hook_path_to_3dbox(); + /* Hook paths to the faces of the box */ + for (int i = 0; i < 6; ++i) { + SP_3DBOX(bc.item)->faces[i]->hook_path_to_3dbox(); + } bc.item->updateRepr(); diff --git a/src/box3d-face.cpp b/src/box3d-face.cpp index 4f85fbf6e..2c2d6209a 100644 --- a/src/box3d-face.cpp +++ b/src/box3d-face.cpp @@ -14,15 +14,24 @@ #include "box3d-face.h" #include -Box3DFace::Box3DFace(SP3DBox *box3d) : dir1 (Box3D::NONE), dir2 (Box3D::NONE), path (NULL), parent_box3d (box3d) -{ - for (int i = 0; i < 4; ++i) { - this->corners[i] = new NR::Point(0, 0); - } -} - -Box3DFace::Box3DFace(SP3DBox *box3d, NR::Point &A, NR::Point &B, NR::Point &C, NR::Point &D) -{ +// FIXME: It's quite redundant to pass the box plus the corners plus the axes. At least the corners can +// theoretically be reconstructed from the box and the axes, but in order to do this we need +// access to box->corners, which is not possible if we only have a forward declaration of SP3DBox +// in box3d-face.h. (But we can't include box3d.h itself because the latter already includes +// box3d-face.h). +Box3DFace::Box3DFace(SP3DBox *box, NR::Point &A, NR::Point &B, NR::Point &C, NR::Point &D, + Box3D::Axis plane, Box3D::FrontOrRear rel_pos) + : path (NULL), parent_box3d (box) + { + /* + Box3D::Axis axis = (rel_pos == Box3D::FRONT ? Box3D::NONE : Box3D::third_axis_direction (plane)); + dir1 = extract_first_axis_direction (plane); + dir2 = extract_second_axis_direction (plane); + set_corners (box->corners[axis], + box->corners[axis ^ dir1], + box->corners[axis ^ dir1 ^ dir2], + box->corners[axis ^ dir2]); + */ set_corners (A, B, C, D); } diff --git a/src/box3d-face.h b/src/box3d-face.h index 3b96937b6..08729150e 100644 --- a/src/box3d-face.h +++ b/src/box3d-face.h @@ -25,11 +25,8 @@ class SP3DBox; class Box3DFace { public: - Box3DFace(SP3DBox *box3d); - Box3DFace(SP3DBox *box3d, NR::Point &A, NR::Point &B, NR::Point &C, NR::Point &D); - //Box3DFace(SP3DBox *box3d, NR::Point const ul, NR::Point const lr, - // Box3D::Axis const dir1, Box3D::Axis const dir2, - // unsigned int shift_count = 0, NR::Maybe pt_align = NR::Nothing(), bool align_along_PL = false); + Box3DFace(SP3DBox *box, NR::Point &A, NR::Point &B, NR::Point &C, NR::Point &D, + Box3D::Axis plane, Box3D::FrontOrRear rel_pos); Box3DFace(Box3DFace const &box3dface); ~Box3DFace(); @@ -57,7 +54,7 @@ private: Box3D::Axis dir2; SPPath *path; - SP3DBox *parent_box3d; // the parent box + SP3DBox *parent_box3d; }; #endif diff --git a/src/box3d.cpp b/src/box3d.cpp index 16bbd3544..1e4cad8b3 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -76,13 +76,27 @@ sp_3dbox_class_init(SP3DBoxClass *klass) } static void -sp_3dbox_init(SP3DBox *box3d) +sp_3dbox_init(SP3DBox *box) { - box3d->faces[4] = new Box3DFace (box3d); - //box3d->faces[4]->hook_path_to_3dbox(); - for (int i = 0; i < 6; ++i) { - if (i == 4) continue; - box3d->faces[i] = NULL; + // We create all faces in the beginning (but only the non-degenerate ones + // should be written to the svg representation later in sp_3dbox_write). + Box3D::Axis cur_plane, axis, dir1, dir2; + Box3D::FrontOrRear cur_pos; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 2; ++j) { + cur_plane = Box3D::planes[i]; + cur_pos = Box3D::face_positions[j]; + // FIXME: The following code could theoretically be moved to + // the constructor of Box3DFace (but see the comment there). + axis = (cur_pos == Box3D::FRONT ? Box3D::NONE : Box3D::third_axis_direction (cur_plane)); + dir1 = extract_first_axis_direction (cur_plane); + dir2 = extract_second_axis_direction (cur_plane); + + box->faces[Box3D::face_to_int(cur_plane ^ cur_pos)] = + new Box3DFace (box, box->corners[axis], box->corners[axis ^ dir1], + box->corners[axis ^ dir1 ^ dir2], box->corners[axis ^ dir2], + cur_plane, cur_pos); + } } } @@ -154,7 +168,6 @@ static Inkscape::XML::Node *sp_3dbox_write(SPObject *object, Inkscape::XML::Node // FIXME: Is tools_isactive(..) more recommended to check for the current context/tool? if (!SP_IS_3DBOX_CONTEXT(inkscape_active_event_context())) return repr; - SP3DBoxContext *bc = SP_3DBOX_CONTEXT(inkscape_active_event_context()); if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object)); @@ -162,14 +175,10 @@ static Inkscape::XML::Node *sp_3dbox_write(SPObject *object, Inkscape::XML::Node repr->setAttribute("sodipodi:type", "inkscape:3dbox"); } - - box3d->faces[4]->set_path_repr(); - if (bc->extruded) { - for (int i = 0; i < 6; ++i) { - if (i == 4) continue; - box3d->faces[i]->set_path_repr(); - } + for (int i = 0; i < 6; ++i) { + box3d->faces[i]->set_path_repr(); } + if (((SPObjectClass *) (parent_class))->write) { ((SPObjectClass *) (parent_class))->write(object, repr, flags); } -- 2.30.2