diff --git a/src/box3d.cpp b/src/box3d.cpp
index 0add188e7cbd1a163b640a5d39f6c146072f798d..72aff25985fcb49d54a502074f6fa6b0225137d1 100644 (file)
--- a/src/box3d.cpp
+++ b/src/box3d.cpp
#include "persp3d-reference.h"
#include "uri.h"
#include "2geom/geom.h"
+#include "sp-guide.h"
+#include "sp-namedview.h"
+#include "prefs-utils.h"
#include "desktop.h"
#include "macros.h"
@@ -47,11 +50,10 @@ static Inkscape::XML::Node *box3d_write(SPObject *object, Inkscape::XML::Node *r
static gchar *box3d_description(SPItem *item);
static NR::Matrix box3d_set_transform(SPItem *item, NR::Matrix const &xform);
+static void box3d_convert_to_guides(SPItem *item);
static void box3d_ref_changed(SPObject *old_ref, SPObject *ref, SPBox3D *box);
static void box3d_ref_modified(SPObject *href, guint flags, SPBox3D *box);
-//static void box3d_ref_changed(SPObject *old_ref, SPObject *ref, Persp3D *persp);
-//static void box3d_ref_modified(SPObject *href, guint flags, Persp3D *persp);
static SPGroupClass *parent_class;
item_class->description = box3d_description;
item_class->set_transform = box3d_set_transform;
+ item_class->convert_to_guides = box3d_convert_to_guides;
}
static void
transf_persp = persp;
}
- /* only transform the perspective once, even it it has several selected boxes */
+ /* only transform the perspective once, even if it has several selected boxes */
if(!persp3d_was_transformed (transf_persp)) {
/* concatenate the affine transformation with the perspective mapping; this
function also triggers repr updates of boxes and the perspective itself */
persp3d_unset_transforms(transf_persp);
}
- /***
- // FIXME: We somehow have to apply the transformation to strokes, patterns, and gradients. How?
NR::Matrix ret(NR::transform(xform));
gdouble const sw = hypot(ret[0], ret[1]);
gdouble const sh = hypot(ret[2], ret[3]);
// Adjust LPE
sp_item_adjust_livepatheffect(item, xform);
}
- ***/
return NR::identity();
}
void box3d_set_center (SPBox3D *box, NR::Point const &new_pos, NR::Point const &old_pos, const Box3D::Axis movement, bool constrained) {
g_return_if_fail ((movement != Box3D::NONE) && (movement != Box3D::XYZ));
+ box->orig_corner0.normalize();
+ box->orig_corner7.normalize();
+
Persp3D *persp = box3d_get_perspective(box);
if (!(movement & Box3D::Z)) {
double coord = (box->orig_corner0[Proj::Z] + box->orig_corner7[Proj::Z]) / 2;
@@ -625,6 +628,7 @@ void box3d_set_center (SPBox3D *box, NR::Point const &new_pos, NR::Point const &
Proj::Pt3 pt_proj (persp->tmat.preimage (new_pos, coord, Proj::Z));
if (constrained) {
Proj::Pt3 old_pos_proj (persp->tmat.preimage (old_pos, coord, Proj::Z));
+ old_pos_proj.normalize();
pt_proj = box3d_snap (box, -1, pt_proj, old_pos_proj);
}
// normalizing pt_proj is essential because we want to mingle affine coordinates
}
/*
- * In der Standard-Perspektive:
- * 2 = vorne
- * 1 = oben
- * 0 = links
- * 3 = rechts
- * 4 = unten
- * 5 = hinten
+ * In standard perspective we have:
+ * 2 = front face
+ * 1 = top face
+ * 0 = left face
+ * 3 = right face
+ * 4 = bottom face
+ * 5 = rear face
*/
/* All VPs infinite */
@@ -992,7 +996,11 @@ box3d_set_new_z_orders_case2 (SPBox3D *box, int z_orders[6], Box3D::Axis central
box3d_aux_set_z_orders (z_orders, 3, 1, 5, 2, 4, 0);
} else {
//g_print ("central axis X (case b3)");
- box3d_aux_set_z_orders (z_orders, 1, 3, 5, 0, 2, 4);
+ if (insidexy == 0) {
+ box3d_aux_set_z_orders (z_orders, 3, 5, 1, 0, 2, 4);
+ } else {
+ box3d_aux_set_z_orders (z_orders, 3, 1, 5, 0, 2, 4);
+ }
}
}
}
@@ -1008,7 +1016,11 @@ box3d_set_new_z_orders_case2 (SPBox3D *box, int z_orders[6], Box3D::Axis central
}
} else {
//g_print ("central axis Y (case b)");
- box3d_aux_set_z_orders (z_orders, 5, 0, 4, 1, 3, 2);
+ if (insideyx == 1) {
+ box3d_aux_set_z_orders (z_orders, 4, 0, 5, 1, 3, 2);
+ } else {
+ box3d_aux_set_z_orders (z_orders, 5, 0, 4, 1, 3, 2);
+ }
}
break;
case Box3D::Z:
@@ -1025,7 +1037,7 @@ box3d_set_new_z_orders_case2 (SPBox3D *box, int z_orders[6], Box3D::Axis central
}
} else {
//g_print ("central axis Z (case b)");
- box3d_aux_set_z_orders (z_orders, 5, 3, 4, 1, 0, 2);
+ box3d_aux_set_z_orders (z_orders, 3, 4, 5, 1, 0, 2);
}
break;
case Box3D::NONE:
@@ -1455,6 +1467,79 @@ box3d_switch_perspectives(SPBox3D *box, Persp3D *old_persp, Persp3D *new_persp,
g_free(href);
}
+/* Converts the 3D box to an ordinary SPGroup, adds it to the XML tree at the same position as
+ the original box and deletes the latter */
+// TODO: Copy over all important attributes (see sp_selected_item_to_curved_repr() for an example)
+SPGroup *
+box3d_convert_to_group(SPBox3D *box) {
+ SPDocument *doc = SP_OBJECT_DOCUMENT(box);
+ Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
+
+ // remember position of the box
+ int pos = SP_OBJECT_REPR(box)->position();
+
+ // create a new group and add the sides (converted to ordinary paths) as its children
+ Inkscape::XML::Node *grepr = xml_doc->createElement("svg:g");
+
+ Inkscape::XML::Node *repr;
+ for (SPObject *child = sp_object_first_child(SP_OBJECT(box)); child != NULL; child = SP_OBJECT_NEXT(child) ) {
+ if (SP_IS_BOX3D_SIDE(child)) {
+ repr = box3d_side_convert_to_path(SP_BOX3D_SIDE(child));
+ grepr->appendChild(repr);
+ } else {
+ g_warning("Non-side object encountered as child of a 3D box.\n");
+ }
+ }
+
+ // add the new group to the box's parent and set remembered position
+ SPObject *parent = SP_OBJECT_PARENT(box);
+ SP_OBJECT_REPR(parent)->appendChild(grepr);
+ grepr->setPosition(pos);
+
+ SP_OBJECT(box)->deleteObject(true);
+
+ return SP_GROUP(doc->getObjectByRepr(grepr));
+}
+
+static inline void
+box3d_push_back_corner_pair(SPBox3D *box, std::list<std::pair<Geom::Point, Geom::Point> > &pts, int c1, int c2) {
+ pts.push_back(std::make_pair(box3d_get_corner_screen(box, c1).to_2geom(),
+ box3d_get_corner_screen(box, c2).to_2geom()));
+}
+
+void
+box3d_convert_to_guides(SPItem *item) {
+ SPBox3D *box = SP_BOX3D(item);
+
+ if (prefs_get_int_attribute("tools.shapes.3dbox", "convertguides", 1) == 0) {
+ sp_item_convert_to_guides(SP_ITEM(box));
+ return;
+ }
+
+ SPDocument *doc = SP_OBJECT_DOCUMENT(box);
+
+ std::list<std::pair<Geom::Point, Geom::Point> > pts;
+
+ /* perspective lines in X direction */
+ box3d_push_back_corner_pair(box, pts, 0, 1);
+ box3d_push_back_corner_pair(box, pts, 2, 3);
+ box3d_push_back_corner_pair(box, pts, 4, 5);
+ box3d_push_back_corner_pair(box, pts, 6, 7);
+
+ /* perspective lines in Y direction */
+ box3d_push_back_corner_pair(box, pts, 0, 2);
+ box3d_push_back_corner_pair(box, pts, 1, 3);
+ box3d_push_back_corner_pair(box, pts, 4, 6);
+ box3d_push_back_corner_pair(box, pts, 5, 7);
+
+ /* perspective lines in Z direction */
+ box3d_push_back_corner_pair(box, pts, 0, 4);
+ box3d_push_back_corner_pair(box, pts, 1, 5);
+ box3d_push_back_corner_pair(box, pts, 2, 6);
+ box3d_push_back_corner_pair(box, pts, 3, 7);
+
+ sp_guide_pt_pairs_to_guides(doc, pts);
+}
/*
Local Variables: