From: cilix42 Date: Wed, 9 Jan 2008 02:40:03 +0000 (+0000) Subject: Convert 3D boxes to ordinary groups before tweaking, ungrouping or applying 'convert... X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=7ed5165239990ad860859dd38806e0ac1736b8ee;p=inkscape.git Convert 3D boxes to ordinary groups before tweaking, ungrouping or applying 'convert to path' (closes LP #179693 and #176646). --- diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index 8cda01f72..9db03c584 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -396,6 +396,19 @@ box3d_side_perspective(Box3DSide *side) { return SP_BOX3D(SP_OBJECT(side)->parent)->persp_ref->getObject(); } +Inkscape::XML::Node * +box3d_side_convert_to_path(Box3DSide *side) { + // TODO: Copy over all important attributes (see sp_selected_item_to_curved_repr() for an example) + SPDocument *doc = SP_OBJECT_DOCUMENT(side); + Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc); + + Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); + repr->setAttribute("d", SP_OBJECT_REPR(side)->attribute("d")); + repr->setAttribute("style", SP_OBJECT_REPR(side)->attribute("style")); + + return repr; +} + /* Local Variables: mode:c++ diff --git a/src/box3d-side.h b/src/box3d-side.h index d2a1d62c9..1b6813f46 100644 --- a/src/box3d-side.h +++ b/src/box3d-side.h @@ -46,6 +46,8 @@ void box3d_side_apply_style (Box3DSide *side); gchar *box3d_side_axes_string(Box3DSide *side); Persp3D *box3d_side_perspective(Box3DSide *side); +Inkscape::XML::Node *box3d_side_convert_to_path(Box3DSide *side); + #endif /* __BOX3D_SIDE_H__ */ /* diff --git a/src/box3d.cpp b/src/box3d.cpp index 3fe9787e3..545c58105 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -1452,6 +1452,39 @@ 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)); +} /* Local Variables: diff --git a/src/box3d.h b/src/box3d.h index d80cf038b..12d6bfc4b 100644 --- a/src/box3d.h +++ b/src/box3d.h @@ -81,6 +81,8 @@ void box3d_mark_transformed(SPBox3D *box); Persp3D *box3d_get_perspective(SPBox3D const *box); void box3d_switch_perspectives(SPBox3D *box, Persp3D *old_persp, Persp3D *new_persp, bool recompute_corners = false); +SPGroup *box3d_convert_to_group(SPBox3D *box); + #endif /* __SP_BOX3D_H__ */ /* diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 744d5ede8..32e2a7bec 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -33,6 +33,7 @@ #include "message-stack.h" #include "selection.h" #include "desktop-handles.h" +#include "box3d.h" #include "path-chemistry.h" @@ -292,6 +293,18 @@ sp_selected_path_to_curves0(gboolean interactive, guint32 /*text_grouping_policy continue; // already a path, and no path effect } + if (SP_IS_BOX3D(item)) { + // convert 3D box to ordinary group of paths; replace the old element in 'selected' with the new group + GSList *sel_it = g_slist_find(selected, item); + sel_it->data = box3d_convert_to_group(SP_BOX3D(item)); + item = SP_ITEM(sel_it->data); + + did = true; + selected = g_slist_remove (selected, item); + + continue; + } + Inkscape::XML::Node *repr = sp_selected_item_to_curved_repr(item, 0); if (!repr) continue; diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 4fc1608cf..aafd48966 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -36,7 +36,6 @@ #include "sp-mask.h" #include "sp-path.h" #include "box3d.h" -#include "box3d-side.h" static void sp_group_class_init (SPGroupClass *klass); static void sp_group_init (SPGroup *group); @@ -328,6 +327,12 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) SPItem *pitem = SP_ITEM (SP_OBJECT_PARENT (gitem)); Inkscape::XML::Node *prepr = SP_OBJECT_REPR (pitem); + if (SP_IS_BOX3D(gitem)) { + group = box3d_convert_to_group(SP_BOX3D(gitem)); + gitem = SP_ITEM(group); + grepr = SP_OBJECT_REPR(gitem); + } + /* Step 1 - generate lists of children objects */ GSList *items = NULL; GSList *objects = NULL; @@ -337,13 +342,6 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) SPItem *citem = SP_ITEM (child); - if (SP_IS_BOX3D_SIDE(child)) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR(child); - // FIXME: This doesn't remove the attribute "inkscape:box3dsidetype". Why? - repr->setAttribute("inkscape:box3dsidetype", NULL); - repr->setAttribute("sodipodi:type", NULL); - } - /* Merging of style */ // this converts the gradient/pattern fill/stroke, if any, to userSpaceOnUse; we need to do // it here _before_ the new transform is set, so as to use the pre-transform bbox diff --git a/src/tweak-context.cpp b/src/tweak-context.cpp index a66f766cf..85831a648 100644 --- a/src/tweak-context.cpp +++ b/src/tweak-context.cpp @@ -71,6 +71,7 @@ #include "isnan.h" #include "prefs-utils.h" #include "style.h" +#include "box3d.h" #include "tweak-context.h" @@ -835,6 +836,12 @@ sp_tweak_dilate (SPTweakContext *tc, NR::Point event_p, NR::Point p, NR::Point v SPItem *item = (SPItem *) items->data; + if (SP_IS_BOX3D(item)) { + // convert 3D boxes to ordinary groups before tweaking their shapes + item = SP_ITEM(box3d_convert_to_group(SP_BOX3D(item))); + selection->add(item); + } + if (tc->mode == TWEAK_MODE_COLORPAINT || tc->mode == TWEAK_MODE_COLORJITTER) { if (do_fill || do_stroke || do_opacity) { if (sp_tweak_color_recursive (tc->mode, item, item_at_point,