X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fbox3d.cpp;h=72aff25985fcb49d54a502074f6fa6b0225137d1;hb=f2c65c84b2e5016ef16907bf15d51ded9c25411e;hp=3397cd6b01088ff24bc7787ff1d5ed2b85af1e49;hpb=e2d40573e3eece043a9e2607f851ed1d32251242;p=inkscape.git diff --git a/src/box3d.cpp b/src/box3d.cpp index 3397cd6b0..72aff2598 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -32,6 +32,9 @@ #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; @@ -97,6 +99,7 @@ box3d_class_init(SPBox3DClass *klass) item_class->description = box3d_description; item_class->set_transform = box3d_set_transform; + item_class->convert_to_guides = box3d_convert_to_guides; } static void @@ -370,7 +373,7 @@ box3d_set_transform(SPItem *item, NR::Matrix const &xform) 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 */ @@ -384,8 +387,6 @@ box3d_set_transform(SPItem *item, NR::Matrix const &xform) 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]); @@ -402,8 +403,10 @@ box3d_set_transform(SPItem *item, NR::Matrix const &xform) // Adjust gradient fill sp_item_adjust_gradient(sideitem, xform); + + // Adjust LPE + sp_item_adjust_livepatheffect(item, xform); } - ***/ return NR::identity(); } @@ -613,6 +616,9 @@ box3d_set_corner (SPBox3D *box, const guint id, NR::Point const &new_pos, const 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; @@ -622,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 @@ -766,13 +773,13 @@ box3d_swap_z_orders (int z_orders[6]) { } /* - * 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 */ @@ -989,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); + } } } } @@ -1005,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: @@ -1022,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: @@ -1452,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 > &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 > 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: