summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: dedcb6c)
raw | patch | inline | side by side (parent: dedcb6c)
author | Maximilian Albert <maximilian.albert@gmail.com> | |
Sat, 26 Dec 2009 00:31:51 +0000 (01:31 +0100) | ||
committer | Maximilian Albert <maximilian.albert@gmail.com> | |
Sat, 26 Dec 2009 00:31:51 +0000 (01:31 +0100) |
diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp
index e3476deb3a00aec82ab547d3c56a08e73a504fd0..c8fbfa8779ff27500679337568fa9df97b53de25 100644 (file)
--- a/src/box3d-context.cpp
+++ b/src/box3d-context.cpp
static void sp_box3d_context_finish(SPEventContext *ec)
{
- Box3DContext *bc = SP_BOX3D_CONTEXT(ec);
- SPDesktop *desktop = ec->desktop;
+ Box3DContext *bc = SP_BOX3D_CONTEXT(ec);
+ SPDesktop *desktop = ec->desktop;
- sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), GDK_CURRENT_TIME);
- sp_box3d_finish(bc);
+ sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), GDK_CURRENT_TIME);
+ sp_box3d_finish(bc);
bc->sel_changed_connection.disconnect();
+// sp_repr_remove_listener_by_data(cc->active_shape_repr, cc);
if (((SPEventContextClass *) parent_class)->finish) {
- ((SPEventContextClass *) parent_class)->finish(ec);
- }
+ ((SPEventContextClass *) parent_class)->finish(ec);
+ }
}
@@ -179,13 +180,14 @@ static void sp_box3d_context_selection_changed(Inkscape::Selection *selection, g
if (selection->perspList().size() == 1) {
// selecting a single box changes the current perspective
- ec->desktop->doc()->current_persp3d = selection->perspList().front();
+ ec->desktop->doc()->setCurrentPersp3D(selection->perspList().front());
}
}
-/* create a default perspective in document defs if none is present
- (can happen after 'vacuum defs' or when a pre-0.46 file is opened) */
-static void sp_box3d_context_check_for_persp_in_defs(SPDocument *document) {
+/* Create a default perspective in document defs if none is present (which can happen, among other
+ * circumstances, after 'vacuum defs' or when a pre-0.46 file is opened).
+ */
+static void sp_box3d_context_ensure_persp_in_defs(SPDocument *document) {
SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document);
bool has_persp = false;
}
if (!has_persp) {
- document->current_persp3d = persp3d_create_xml_element (document);
+ document->setCurrentPersp3D(persp3d_create_xml_element (document));
}
}
((SPEventContextClass *) parent_class)->setup(ec);
}
- sp_box3d_context_check_for_persp_in_defs(sp_desktop_document (ec->desktop));
-
ec->shape_editor = new ShapeEditor(ec->desktop);
SPItem *item = sp_desktop_selection(ec->desktop)->singleItem();
@@ -267,13 +267,13 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
static bool dragging;
SPDesktop *desktop = event_context->desktop;
+ SPDocument *document = sp_desktop_document (desktop);
Inkscape::Selection *selection = sp_desktop_selection (desktop);
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int const snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12);
Box3DContext *bc = SP_BOX3D_CONTEXT(event_context);
- g_assert (SP_ACTIVE_DOCUMENT->current_persp3d);
- Persp3D *cur_persp = SP_ACTIVE_DOCUMENT->current_persp3d;
+ Persp3D *cur_persp = document->getCurrentPersp3D();
event_context->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
@@ -300,8 +300,14 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
bc->drag_ptB = from_2geom(button_dt);
bc->drag_ptC = from_2geom(button_dt);
+ // This can happen after saving when the last remaining perspective was purged and must be recreated.
+ if (!cur_persp) {
+ sp_box3d_context_ensure_persp_in_defs(document);
+ cur_persp = document->getCurrentPersp3D();
+ }
+
/* Projective preimages of clicked point under current perspective */
- bc->drag_origin_proj = cur_persp->tmat.preimage (from_2geom(button_dt), 0, Proj::Z);
+ bc->drag_origin_proj = cur_persp->perspective_impl->tmat.preimage (from_2geom(button_dt), 0, Proj::Z);
bc->drag_ptB_proj = bc->drag_origin_proj;
bc->drag_ptC_proj = bc->drag_origin_proj;
bc->drag_ptC_proj.normalize();
@@ -355,7 +361,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
bc->drag_ptB = from_2geom(motion_dt);
bc->drag_ptC = from_2geom(motion_dt);
- bc->drag_ptB_proj = cur_persp->tmat.preimage (from_2geom(motion_dt), 0, Proj::Z);
+ bc->drag_ptB_proj = cur_persp->perspective_impl->tmat.preimage (from_2geom(motion_dt), 0, Proj::Z);
bc->drag_ptC_proj = bc->drag_ptB_proj;
bc->drag_ptC_proj.normalize();
bc->drag_ptC_proj[Proj::Z] = 0.25;
@@ -364,16 +370,16 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
// perspective line from drag_ptB to vanishing point Y.
if (!bc->ctrl_dragged) {
/* snapping */
- Box3D::PerspectiveLine pline (bc->drag_ptB, Proj::Z, SP_ACTIVE_DOCUMENT->current_persp3d);
+ Box3D::PerspectiveLine pline (bc->drag_ptB, Proj::Z, document->getCurrentPersp3D());
bc->drag_ptC = pline.closest_to (from_2geom(motion_dt));
bc->drag_ptB_proj.normalize();
- bc->drag_ptC_proj = cur_persp->tmat.preimage (bc->drag_ptC, bc->drag_ptB_proj[Proj::X], Proj::X);
+ bc->drag_ptC_proj = cur_persp->perspective_impl->tmat.preimage (bc->drag_ptC, bc->drag_ptB_proj[Proj::X], Proj::X);
} else {
bc->drag_ptC = from_2geom(motion_dt);
bc->drag_ptB_proj.normalize();
- bc->drag_ptC_proj = cur_persp->tmat.preimage (from_2geom(motion_dt), bc->drag_ptB_proj[Proj::X], Proj::X);
+ bc->drag_ptC_proj = cur_persp->perspective_impl->tmat.preimage (from_2geom(motion_dt), bc->drag_ptB_proj[Proj::X], Proj::X);
}
Geom::Point pt2g = to_2geom(bc->drag_ptC);
m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE);
@@ -424,43 +430,43 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
break;
case GDK_bracketright:
- persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::X, -180/snaps, MOD__ALT);
- sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::X, -180/snaps, MOD__ALT);
+ sp_document_done(document, SP_VERB_CONTEXT_3DBOX,
_("Change perspective (angle of PLs)"));
ret = true;
break;
case GDK_bracketleft:
- persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::X, 180/snaps, MOD__ALT);
- sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::X, 180/snaps, MOD__ALT);
+ sp_document_done(document, SP_VERB_CONTEXT_3DBOX,
_("Change perspective (angle of PLs)"));
ret = true;
break;
case GDK_parenright:
- persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Y, -180/snaps, MOD__ALT);
- sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Y, -180/snaps, MOD__ALT);
+ sp_document_done(document, SP_VERB_CONTEXT_3DBOX,
_("Change perspective (angle of PLs)"));
ret = true;
break;
case GDK_parenleft:
- persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Y, 180/snaps, MOD__ALT);
- sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Y, 180/snaps, MOD__ALT);
+ sp_document_done(document, SP_VERB_CONTEXT_3DBOX,
_("Change perspective (angle of PLs)"));
ret = true;
break;
case GDK_braceright:
- persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Z, -180/snaps, MOD__ALT);
- sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Z, -180/snaps, MOD__ALT);
+ sp_document_done(document, SP_VERB_CONTEXT_3DBOX,
_("Change perspective (angle of PLs)"));
ret = true;
break;
case GDK_braceleft:
- persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Z, 180/snaps, MOD__ALT);
- sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
+ persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Z, 180/snaps, MOD__ALT);
+ sp_document_done(document, SP_VERB_CONTEXT_3DBOX,
_("Change perspective (angle of PLs)"));
ret = true;
break;
@@ -468,7 +474,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
/* TODO: what is this???
case GDK_O:
if (MOD__CTRL && MOD__SHIFT) {
- Box3D::create_canvas_point(persp3d_get_VP(inkscape_active_document()->current_persp3d, Proj::W).affine(),
+ Box3D::create_canvas_point(persp3d_get_VP(document()->getCurrentPersp3D(), Proj::W).affine(),
6, 0xff00ff00);
}
ret = true;
@@ -483,6 +489,16 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
}
break;
+ case GDK_p:
+ case GDK_P:
+ if (MOD__SHIFT_ONLY) {
+ if (document->getCurrentPersp3D()) {
+ persp3d_print_debugging_info (document->getCurrentPersp3D());
+ }
+ ret = true;
+ }
+ break;
+
case GDK_x:
case GDK_X:
if (MOD__ALT_ONLY) {
// TODO: It would be nice to show the VPs during dragging, but since there is no selection
// at this point (only after finishing the box), we must do this "manually"
- /**** bc._vpdrag->updateDraggers(); ****/
+ /* bc._vpdrag->updateDraggers(); */
sp_canvas_force_full_redraw_after_interruptions(desktop->canvas, 5);
}
if ( bc->item != NULL ) {
SPDesktop * desktop = SP_EVENT_CONTEXT_DESKTOP(bc);
SPDocument *doc = sp_desktop_document(desktop);
- if (!doc || !doc->current_persp3d)
+ if (!doc || !doc->getCurrentPersp3D())
return;
SPBox3D *box = SP_BOX3D(bc->item);
diff --git a/src/box3d.cpp b/src/box3d.cpp
index 93efa5c35183589ea7e604066d7afb9d93e8b52d..460465637de0d0e1f1290f40733cf3fb8f74105a 100644 (file)
--- a/src/box3d.cpp
+++ b/src/box3d.cpp
// TODO: Create/link to the correct perspective
SPDocument *doc = SP_OBJECT_DOCUMENT(box);
- if (!doc) {
- g_print ("No document for the box!!!!\n");
+ if (!doc)
return;
- }
box->persp_ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(box3d_ref_changed), box));
if (box->persp_href) {
g_free(box->persp_href);
}
+
+ // We have to store this here because the Persp3DReference gets destroyed below, but we need to
+ // access it to call persp3d_remove_box(), which cannot be called earlier because the reference
+ // needs to be destroyed first.
+ Persp3D *persp = box3d_get_perspective(box);
+
if (box->persp_ref) {
box->persp_ref->detach();
delete box->persp_ref;
box->persp_ref = NULL;
}
- //persp3d_remove_box (box3d_get_perspective(box), box);
+ if (persp) {
+ persp3d_remove_box (persp, box);
+ /*
+ // TODO: This deletes a perspective when the last box referring to it is gone. Eventually,
+ // it would be nice to have this but currently it crashes when undoing/redoing box deletion
+ // Reason: When redoing a box deletion, the associated perspective is deleted twice, first
+ // by the following code and then again by the redo mechanism! Perhaps we should perform
+ // deletion of the perspective from another location "outside" the undo/redo mechanism?
+ if (persp->perspective_impl->boxes.empty()) {
+ SPDocument *doc = SP_OBJECT_DOCUMENT(box);
+ persp->deleteObject();
+ doc->setCurrentPersp3D(persp3d_document_first_persp(doc));
+ }
+ */
+ }
if (((SPObjectClass *) parent_class)->release)
((SPObjectClass *) parent_class)->release(object);
@@ -278,7 +296,7 @@ static Inkscape::XML::Node *box3d_write(SPObject *object, Inkscape::XML::Documen
repr->setAttribute("inkscape:perspectiveID", uri_string);
g_free(uri_string);
} else {
- Inkscape::XML::Node *persp_repr = SP_OBJECT_REPR(doc->current_persp3d);
+ Inkscape::XML::Node *persp_repr = SP_OBJECT_REPR(doc->getCurrentPersp3D());
const gchar *persp_id = persp_repr->attribute("id");
gchar *href = g_strdup_printf("#%s", persp_id);
repr->setAttribute("inkscape:perspectiveID", href);
std::list<SPBox3D *> selboxes = sp_desktop_selection(inkscape_active_desktop())->box3DList();
/* create a new perspective as a copy of the current one and link the selected boxes to it */
- transf_persp = persp3d_create_xml_element (SP_OBJECT_DOCUMENT(persp), persp);
+ transf_persp = persp3d_create_xml_element (SP_OBJECT_DOCUMENT(persp), persp->perspective_impl);
for (std::list<SPBox3D *>::iterator b = selboxes.begin(); b != selboxes.end(); ++b) {
box3d_switch_perspectives(*b, persp, transf_persp);
}
Geom::Matrix const i2d (sp_item_i2d_affine (SP_ITEM(box)));
if (item_coords) {
- return box3d_get_perspective(box)->tmat.image(proj_corner).affine() * i2d.inverse();
+ return box3d_get_perspective(box)->perspective_impl->tmat.image(proj_corner).affine() * i2d.inverse();
} else {
- return box3d_get_perspective(box)->tmat.image(proj_corner).affine();
+ return box3d_get_perspective(box)->perspective_impl->tmat.image(proj_corner).affine();
}
}
return Geom::Point (NR_HUGE, NR_HUGE);
}
Geom::Matrix const i2d (sp_item_i2d_affine (SP_ITEM(box)));
- return box3d_get_perspective(box)->tmat.image(proj_center).affine() * i2d.inverse();
+ return box3d_get_perspective(box)->perspective_impl->tmat.image(proj_center).affine() * i2d.inverse();
}
/*
@@ -461,13 +479,13 @@ box3d_snap (SPBox3D *box, int id, Proj::Pt3 const &pt_proj, Proj::Pt3 const &sta
Proj::Pt3 D_proj (x_coord, y_coord + diff_y, z_coord, 1.0);
Proj::Pt3 E_proj (x_coord - diff_x, y_coord + diff_y, z_coord, 1.0);
- Persp3D *persp = box3d_get_perspective(box);
- Geom::Point A = persp->tmat.image(A_proj).affine();
- Geom::Point B = persp->tmat.image(B_proj).affine();
- Geom::Point C = persp->tmat.image(C_proj).affine();
- Geom::Point D = persp->tmat.image(D_proj).affine();
- Geom::Point E = persp->tmat.image(E_proj).affine();
- Geom::Point pt = persp->tmat.image(pt_proj).affine();
+ Persp3DImpl *persp_impl = box3d_get_perspective(box)->perspective_impl;
+ Geom::Point A = persp_impl->tmat.image(A_proj).affine();
+ Geom::Point B = persp_impl->tmat.image(B_proj).affine();
+ Geom::Point C = persp_impl->tmat.image(C_proj).affine();
+ Geom::Point D = persp_impl->tmat.image(D_proj).affine();
+ Geom::Point E = persp_impl->tmat.image(E_proj).affine();
+ Geom::Point pt = persp_impl->tmat.image(pt_proj).affine();
// TODO: Replace these lines between corners with lines from a corner to a vanishing point
// (this might help to prevent rounding errors if the box is small)
@@ -523,7 +541,7 @@ box3d_snap (SPBox3D *box, int id, Proj::Pt3 const &pt_proj, Proj::Pt3 const &sta
remember_snap_index = snap_index;
result = snap_pts[snap_index];
}
- return box3d_get_perspective(box)->tmat.preimage (result, z_coord, Proj::Z);
+ return box3d_get_perspective(box)->perspective_impl->tmat.preimage (result, z_coord, Proj::Z);
}
void
@@ -535,8 +553,9 @@ box3d_set_corner (SPBox3D *box, const guint id, Geom::Point const &new_pos, cons
/* update corners 0 and 7 according to which handle was moved and to the axes of movement */
if (!(movement & Box3D::Z)) {
- Proj::Pt3 pt_proj (box3d_get_perspective(box)->tmat.preimage (new_pos, (id < 4) ? box->orig_corner0[Proj::Z] :
- box->orig_corner7[Proj::Z], Proj::Z));
+ Persp3DImpl *persp_impl = box3d_get_perspective(box)->perspective_impl;
+ Proj::Pt3 pt_proj (persp_impl->tmat.preimage (new_pos, (id < 4) ? box->orig_corner0[Proj::Z] :
+ box->orig_corner7[Proj::Z], Proj::Z));
if (constrained) {
pt_proj = box3d_snap (box, id, pt_proj, box3d_get_proj_corner (id, box->save_corner0, box->save_corner7));
}
@@ -553,13 +572,14 @@ box3d_set_corner (SPBox3D *box, const guint id, Geom::Point const &new_pos, cons
1.0);
} else {
Persp3D *persp = box3d_get_perspective(box);
- Box3D::PerspectiveLine pl(persp->tmat.image(
+ Persp3DImpl *persp_impl = box3d_get_perspective(box)->perspective_impl;
+ Box3D::PerspectiveLine pl(persp_impl->tmat.image(
box3d_get_proj_corner (id, box->save_corner0, box->save_corner7)).affine(),
Proj::Z, persp);
Geom::Point new_pos_snapped(pl.closest_to(new_pos));
- Proj::Pt3 pt_proj (persp->tmat.preimage (new_pos_snapped,
- box3d_get_proj_corner (box, id)[(movement & Box3D::Y) ? Proj::X : Proj::Y],
- (movement & Box3D::Y) ? Proj::X : Proj::Y));
+ Proj::Pt3 pt_proj (persp_impl->tmat.preimage (new_pos_snapped,
+ box3d_get_proj_corner (box, id)[(movement & Box3D::Y) ? Proj::X : Proj::Y],
+ (movement & Box3D::Y) ? Proj::X : Proj::Y));
bool corner0_move_x = !(id & Box3D::X) && (movement & Box3D::X);
bool corner0_move_y = !(id & Box3D::Y) && (movement & Box3D::Y);
bool corner7_move_x = (id & Box3D::X) && (movement & Box3D::X);
@@ -590,9 +610,9 @@ void box3d_set_center (SPBox3D *box, Geom::Point const &new_pos, Geom::Point con
double radx = (box->orig_corner7[Proj::X] - box->orig_corner0[Proj::X]) / 2;
double rady = (box->orig_corner7[Proj::Y] - box->orig_corner0[Proj::Y]) / 2;
- Proj::Pt3 pt_proj (persp->tmat.preimage (new_pos, coord, Proj::Z));
+ Proj::Pt3 pt_proj (persp->perspective_impl->tmat.preimage (new_pos, coord, Proj::Z));
if (constrained) {
- Proj::Pt3 old_pos_proj (persp->tmat.preimage (old_pos, coord, Proj::Z));
+ Proj::Pt3 old_pos_proj (persp->perspective_impl->tmat.preimage (old_pos, coord, Proj::Z));
old_pos_proj.normalize();
pt_proj = box3d_snap (box, -1, pt_proj, old_pos_proj);
}
@@ -612,7 +632,7 @@ void box3d_set_center (SPBox3D *box, Geom::Point const &new_pos, Geom::Point con
Box3D::PerspectiveLine pl(old_pos, Proj::Z, persp);
Geom::Point new_pos_snapped(pl.closest_to(new_pos));
- Proj::Pt3 pt_proj (persp->tmat.preimage (new_pos_snapped, coord, Proj::X));
+ Proj::Pt3 pt_proj (persp->perspective_impl->tmat.preimage (new_pos_snapped, coord, Proj::X));
/* normalizing pt_proj is essential because we want to mingle affine coordinates */
pt_proj.normalize();
{
Persp3D *persp = box3d_get_perspective(box);
g_return_if_fail (persp);
+ Persp3DImpl *persp_impl = persp->perspective_impl;
//box->orig_corner0.normalize();
//box->orig_corner7.normalize();
double coord = (box->orig_corner0[axis] > box->orig_corner7[axis]) ?
default:
return;
}
- corner1 = persp->tmat.image(c1).affine();
- corner2 = persp->tmat.image(c2).affine();
- corner3 = persp->tmat.image(c3).affine();
- corner4 = persp->tmat.image(c4).affine();
+ corner1 = persp_impl->tmat.image(c1).affine();
+ corner2 = persp_impl->tmat.image(c2).affine();
+ corner3 = persp_impl->tmat.image(c3).affine();
+ corner4 = persp_impl->tmat.image(c4).affine();
}
/* Auxiliary function: Checks whether the half-line from A to B crosses the line segment joining C and D */
Geom::Point dirs[3];
for (int i = 0; i < 3; ++i) {
dirs[i] = persp3d_get_PL_dir_from_pt(persp, c3, Box3D::toProj(Box3D::axes[i]));
- if (persp3d_VP_is_finite(persp, Proj::axes[i])) {
+ if (persp3d_VP_is_finite(persp->perspective_impl, Proj::axes[i])) {
num_finite++;
axis_finite = Box3D::axes[i];
} else {
@@ -1212,7 +1233,7 @@ box3d_pt_lies_in_PL_sector (SPBox3D const *box, Geom::Point const &pt, int id1,
Geom::Point c2(box3d_get_corner_screen(box, id2, false));
int ret = 0;
- if (persp3d_VP_is_finite(persp, Box3D::toProj(axis))) {
+ if (persp3d_VP_is_finite(persp->perspective_impl, Box3D::toProj(axis))) {
Geom::Point vp(persp3d_get_VP(persp, Box3D::toProj(axis)).affine());
Geom::Point v1(c1 - vp);
Geom::Point v2(c2 - vp);
box3d_VP_lies_in_PL_sector (SPBox3D const *box, Proj::Axis vpdir, int id1, int id2, Box3D::Axis axis) {
Persp3D *persp = box3d_get_perspective(box);
- if (!persp3d_VP_is_finite(persp, vpdir)) {
+ if (!persp3d_VP_is_finite(persp->perspective_impl, vpdir)) {
return 0;
} else {
return box3d_pt_lies_in_PL_sector(box, persp3d_get_VP(persp, vpdir).affine(), id1, id2, axis);
@@ -1360,8 +1381,8 @@ box3d_switch_perspectives(SPBox3D *box, Persp3D *old_persp, Persp3D *new_persp,
Geom::Point corner0_screen = box3d_get_corner_screen(box, 0, false);
Geom::Point corner7_screen = box3d_get_corner_screen(box, 7, false);
- box->orig_corner0 = new_persp->tmat.preimage(corner0_screen, z0, Proj::Z);
- box->orig_corner7 = new_persp->tmat.preimage(corner7_screen, z7, Proj::Z);
+ box->orig_corner0 = new_persp->perspective_impl->tmat.preimage(corner0_screen, z0, Proj::Z);
+ box->orig_corner7 = new_persp->perspective_impl->tmat.preimage(corner7_screen, z7, Proj::Z);
}
persp3d_remove_box (old_persp, box);
diff --git a/src/document.cpp b/src/document.cpp
index a3ad6f7beb1486a4bc236e6d0ff44213b2d89ef5..df77dde6413477512d601a226f70256d5d4590cf 100644 (file)
--- a/src/document.cpp
+++ b/src/document.cpp
rerouting_handler_id(0),
profileManager(0), // deferred until after other initialization
router(new Avoid::Router(Avoid::PolyLineRouting|Avoid::OrthogonalRouting)),
- perspectives(0),
current_persp3d(0),
_collection_queue(0),
oldSignalsConnected(false)
//delete this->_whiteboard_session_manager;
}
-void SPDocument::add_persp3d (Persp3D * const /*persp*/)
-{
- SPDefs *defs = SP_ROOT(this->root)->defs;
- for (SPObject *i = sp_object_first_child(SP_OBJECT(defs)); i != NULL; i = SP_OBJECT_NEXT(i) ) {
- if (SP_IS_PERSP3D(i)) {
- g_print ("Encountered a Persp3D in defs\n");
- }
+Persp3D *
+SPDocument::getCurrentPersp3D() {
+ // Check if current_persp3d is still valid
+ std::vector<Persp3D*> plist;
+ getPerspectivesInDefs(plist);
+ for (unsigned int i = 0; i < plist.size(); ++i) {
+ if (current_persp3d == plist[i])
+ return current_persp3d;
}
- g_print ("Adding Persp3D to defs\n");
- persp3d_create_xml_element (this);
+ // If not, return the first perspective in defs (which may be NULL of none exists)
+ current_persp3d = persp3d_document_first_persp (this);
+
+ return current_persp3d;
}
-void SPDocument::remove_persp3d (Persp3D * const /*persp*/)
-{
- // TODO: Delete the repr, maybe perform a check if any boxes are still linked to the perspective.
- // Anything else?
- g_print ("Please implement deletion of perspectives here.\n");
+Persp3DImpl *
+SPDocument::getCurrentPersp3DImpl() {
+ return current_persp3d_impl;
}
+void
+SPDocument::setCurrentPersp3D(Persp3D * const persp) {
+ current_persp3d = persp;
+ //current_persp3d_impl = persp->perspective_impl;
+}
+
+void
+SPDocument::getPerspectivesInDefs(std::vector<Persp3D*> &list) {
+ SPDefs *defs = SP_ROOT(this->root)->defs;
+ for (SPObject *i = sp_object_first_child(SP_OBJECT(defs)); i != NULL; i = SP_OBJECT_NEXT(i) ) {
+ if (SP_IS_PERSP3D(i))
+ list.push_back(SP_PERSP3D(i));
+ }
+}
+
+/**
void SPDocument::initialize_current_persp3d()
{
this->current_persp3d = persp3d_document_first_persp(this);
this->current_persp3d = persp3d_create_xml_element(this);
}
}
+**/
unsigned long SPDocument::serial() const {
return priv->serial;
inkscape_ref();
}
- // Remark: Here, we used to create a "currentpersp3d" element in the document defs.
- // But this is probably a bad idea since we need to adapt it for every change of selection, which will
- // completely clutter the undo history. Maybe rather save it to prefs on exit and re-read it on startup?
- document->initialize_current_persp3d();
+ // Check if the document already has a perspective (e.g., when opening an existing
+ // document). If not, create a new one and set it as the current perspective.
+ document->setCurrentPersp3D(persp3d_document_first_persp(document));
+ if (!document->getCurrentPersp3D()) {
+ //document->setCurrentPersp3D(persp3d_create_xml_element (document));
+ Persp3DImpl *persp_impl = new Persp3DImpl();
+ document->setCurrentPersp3DImpl(persp_impl);
+ }
sp_document_set_undo_sensitive(document, true);
{
// printf("Finishing Reconstruction\n");
priv->_reconstruction_finish_signal.emit();
-
+
+/**
// Reference to the old persp3d object is invalid after reconstruction.
initialize_current_persp3d();
return;
+**/
}
sigc::connection SPDocument::connectCommit(SPDocument::CommitSignal::slot_type slot)
diff --git a/src/document.h b/src/document.h
index 06174c265f593b402151200b2fcb2e6a221f6c26..e83c37a968a2d4584cd020ed5173d70752aa7207 100644 (file)
--- a/src/document.h
+++ b/src/document.h
class SP3DBox;
class Persp3D;
+class Persp3DImpl;
namespace Proj {
class TransfMat3x4;
// Instance of the connector router
Avoid::Router *router;
- GSList *perspectives;
-
- Persp3D *current_persp3d; // "currently active" perspective (e.g., newly created boxes are attached to this one)
-
GSList *_collection_queue;
bool oldSignalsConnected;
- void add_persp3d(Persp3D * const persp);
- void remove_persp3d(Persp3D * const persp);
- void initialize_current_persp3d();
+ void setCurrentPersp3D(Persp3D * const persp);
+ inline void setCurrentPersp3DImpl(Persp3DImpl * const persp_impl) { current_persp3d_impl = persp_impl; }
+ /*
+ * getCurrentPersp3D returns current_persp3d (if non-NULL) or the first
+ * perspective in the defs. If no perspective exists, returns NULL.
+ */
+ Persp3D * getCurrentPersp3D();
+ Persp3DImpl * getCurrentPersp3DImpl();
+ void getPerspectivesInDefs(std::vector<Persp3D*> &list);
+ unsigned int numPerspectivesInDefs() {
+ std::vector<Persp3D*> list;
+ getPerspectivesInDefs(list);
+ return list.size();
+ }
+
+ //void initialize_current_persp3d();
sigc::connection connectModified(ModifiedSignal::slot_type slot);
sigc::connection connectURISet(URISetSignal::slot_type slot);
SPDocument(SPDocument const &); // no copy
void operator=(SPDocument const &); // no assign
+ Persp3D *current_persp3d; /**< Currently 'active' perspective (to which, e.g., newly created boxes are attached) */
+ Persp3DImpl *current_persp3d_impl;
+
public:
sigc::connection connectReconstructionStart(ReconstructionStart::slot_type slot);
sigc::connection connectReconstructionFinish(ReconstructionFinish::slot_type slot);
index 091a4d9ae2b90deee7799e0d840862ce45f42660..3d18318c5c53ff0bbe899e2a5cd3e40e0e312ec1 100644 (file)
Persp3D *persp = persp3d_document_first_persp(inkscape_active_document());
- Proj::TransfMat3x4 pmat = persp->tmat;
+ Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat;
pmat.copy_tmat(tmat);
}
index 43b0e82b1f5431899b2c55b6f8b6f5190f6e2c62..7c2ce31bf6136bf5996d2603239e41eaa3d31e2e 100644 (file)
--- a/src/persp3d-reference.h
+++ b/src/persp3d-reference.h
#include "uri-references.h"
#include <sigc++/sigc++.h>
+#include "persp3d.h"
class SPObject;
-class Persp3D;
namespace Inkscape {
namespace XML {
~Persp3DReference();
Persp3D *getObject() const {
- return (Persp3D *)URIReference::getObject();
+ return SP_PERSP3D(URIReference::getObject());
}
SPObject *owner;
diff --git a/src/persp3d.cpp b/src/persp3d.cpp
index 916e9f25f421fe071452b070e4088abfb2cf9bdf..3f1e8851fe7075185e9f3b4e3a8c7781cb5ac8cf 100644 (file)
--- a/src/persp3d.cpp
+++ b/src/persp3d.cpp
#include <glibmm/i18n.h>
static void persp3d_class_init(Persp3DClass *klass);
-static void persp3d_init(Persp3D *stop);
+static void persp3d_init(Persp3D *persp);
static void persp3d_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
static void persp3d_release(SPObject *object);
static int global_counter = 0;
+/* Constructor/destructor for the internal class */
+
+Persp3DImpl::Persp3DImpl() {
+ tmat = Proj::TransfMat3x4 ();
+
+ boxes_transformed = new std::map<SPBox3D *, bool>;
+ boxes_transformed->clear();
+ document = NULL;
+
+ my_counter = global_counter++;
+}
+
+Persp3DImpl::~Persp3DImpl() {
+ delete boxes_transformed;
+}
+
/**
* Registers Persp3d class and returns its type.
*/
static void
persp3d_init(Persp3D *persp)
{
- persp->tmat = Proj::TransfMat3x4 ();
-
- persp->boxes_transformed = new std::map<SPBox3D *, bool>;
- persp->boxes_transformed->clear();
- persp->document = NULL;
-
- persp->my_counter = global_counter++;
+ persp->perspective_impl = new Persp3DImpl();
}
/**
@@ -124,8 +134,8 @@ static void persp3d_build(SPObject *object, SPDocument *document, Inkscape::XML:
* Virtual release of Persp3D members before destruction.
*/
static void persp3d_release(SPObject *object) {
- Persp3D *persp = SP_PERSP3D (object);
- delete persp->boxes_transformed;
+ Persp3D *persp = SP_PERSP3D(object);
+ delete persp->perspective_impl;
SP_OBJECT_REPR(object)->removeListenerByData(object);
}
static void
persp3d_set(SPObject *object, unsigned key, gchar const *value)
{
- Persp3D *persp = SP_PERSP3D (object);
+ Persp3DImpl *persp_impl = SP_PERSP3D(object)->perspective_impl;
switch (key) {
case SP_ATTR_INKSCAPE_PERSP3D_VP_X: {
if (value) {
Proj::Pt2 new_image (value);
- persp3d_update_with_point (persp, Proj::X, new_image);
+ persp3d_update_with_point (persp_impl, Proj::X, new_image);
}
break;
}
case SP_ATTR_INKSCAPE_PERSP3D_VP_Y: {
if (value) {
Proj::Pt2 new_image (value);
- persp3d_update_with_point (persp, Proj::Y, new_image);
+ persp3d_update_with_point (persp_impl, Proj::Y, new_image);
break;
}
}
case SP_ATTR_INKSCAPE_PERSP3D_VP_Z: {
if (value) {
Proj::Pt2 new_image (value);
- persp3d_update_with_point (persp, Proj::Z, new_image);
+ persp3d_update_with_point (persp_impl, Proj::Z, new_image);
break;
}
}
case SP_ATTR_INKSCAPE_PERSP3D_ORIGIN: {
if (value) {
Proj::Pt2 new_image (value);
- persp3d_update_with_point (persp, Proj::W, new_image);
+ persp3d_update_with_point (persp_impl, Proj::W, new_image);
break;
}
}
}
Persp3D *
-persp3d_create_xml_element (SPDocument *document, Persp3D *dup) {// if dup is given, copy the attributes over
+persp3d_create_xml_element (SPDocument *document, Persp3DImpl *dup) {// if dup is given, copy the attributes over
SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document);
Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document);
Inkscape::XML::Node *repr;
- if (dup) {
- repr = SP_OBJECT_REPR(dup)->duplicate (xml_doc);
- } else {
- /* if no perspective is given, create a default one */
- repr = xml_doc->createElement("inkscape:perspective");
- repr->setAttribute("sodipodi:type", "inkscape:persp3d");
- Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, sp_document_height(document)/2, 1.0);
- Proj::Pt2 proj_vp_y = Proj::Pt2 ( 0.0,1000.0, 0.0);
- Proj::Pt2 proj_vp_z = Proj::Pt2 (sp_document_width(document), sp_document_height(document)/2, 1.0);
- Proj::Pt2 proj_origin = Proj::Pt2 (sp_document_width(document)/2, sp_document_height(document)/3, 1.0);
+ /* if no perspective is given, create a default one */
+ repr = xml_doc->createElement("inkscape:perspective");
+ repr->setAttribute("sodipodi:type", "inkscape:persp3d");
- gchar *str = NULL;
- str = proj_vp_x.coord_string();
- repr->setAttribute("inkscape:vp_x", str);
- g_free (str);
- str = proj_vp_y.coord_string();
- repr->setAttribute("inkscape:vp_y", str);
- g_free (str);
- str = proj_vp_z.coord_string();
- repr->setAttribute("inkscape:vp_z", str);
- g_free (str);
- str = proj_origin.coord_string();
- repr->setAttribute("inkscape:persp3d-origin", str);
- g_free (str);
- }
+ Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, sp_document_height(document)/2, 1.0);
+ Proj::Pt2 proj_vp_y = Proj::Pt2 (0.0, 1000.0, 0.0);
+ Proj::Pt2 proj_vp_z = Proj::Pt2 (sp_document_width(document), sp_document_height(document)/2, 1.0);
+ Proj::Pt2 proj_origin = Proj::Pt2 (sp_document_width(document)/2, sp_document_height(document)/3, 1.0);
+
+ if (dup) {
+ proj_vp_x = dup->tmat.column (Proj::X);
+ proj_vp_y = dup->tmat.column (Proj::Y);
+ proj_vp_z = dup->tmat.column (Proj::Z);
+ proj_origin = dup->tmat.column (Proj::W);
+ }
+
+ gchar *str = NULL;
+ str = proj_vp_x.coord_string();
+ repr->setAttribute("inkscape:vp_x", str);
+ g_free (str);
+ str = proj_vp_y.coord_string();
+ repr->setAttribute("inkscape:vp_y", str);
+ g_free (str);
+ str = proj_vp_z.coord_string();
+ repr->setAttribute("inkscape:vp_z", str);
+ g_free (str);
+ str = proj_origin.coord_string();
+ repr->setAttribute("inkscape:persp3d-origin", str);
+ g_free (str);
/* Append the new persp3d to defs */
SP_OBJECT_REPR(defs)->addChild(repr, NULL);
static Inkscape::XML::Node *
persp3d_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
- Persp3D *persp = SP_PERSP3D(object);
+ Persp3DImpl *persp_impl = SP_PERSP3D(object)->perspective_impl;
if ((flags & SP_OBJECT_WRITE_BUILD & SP_OBJECT_WRITE_EXT) && !repr) {
// this is where we end up when saving as plain SVG (also in other circumstances?);
@@ -268,16 +282,16 @@ persp3d_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML:
if (flags & SP_OBJECT_WRITE_EXT) {
gchar *str = NULL; // FIXME: Should this be freed each time we set an attribute or only in the end or at all?
- str = persp3d_pt_to_str (persp, Proj::X);
+ str = persp3d_pt_to_str (persp_impl, Proj::X);
repr->setAttribute("inkscape:vp_x", str);
- str = persp3d_pt_to_str (persp, Proj::Y);
+ str = persp3d_pt_to_str (persp_impl, Proj::Y);
repr->setAttribute("inkscape:vp_y", str);
- str = persp3d_pt_to_str (persp, Proj::Z);
+ str = persp3d_pt_to_str (persp_impl, Proj::Z);
repr->setAttribute("inkscape:vp_z", str);
- str = persp3d_pt_to_str (persp, Proj::W);
+ str = persp3d_pt_to_str (persp_impl, Proj::W);
repr->setAttribute("inkscape:persp3d-origin", str);
}
@@ -289,7 +303,7 @@ persp3d_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML:
/* convenience wrapper around persp3d_get_finite_dir() and persp3d_get_infinite_dir() */
Geom::Point persp3d_get_PL_dir_from_pt (Persp3D *persp, Geom::Point const &pt, Proj::Axis axis) {
- if (persp3d_VP_is_finite(persp, axis)) {
+ if (persp3d_VP_is_finite(persp->perspective_impl, axis)) {
return persp3d_get_finite_dir(persp, pt, axis);
} else {
return persp3d_get_infinite_dir(persp, axis);
double
persp3d_get_infinite_angle (Persp3D *persp, Proj::Axis axis) {
- return persp->tmat.get_infinite_angle(axis);
+ return persp->perspective_impl->tmat.get_infinite_angle(axis);
}
bool
-persp3d_VP_is_finite (Persp3D *persp, Proj::Axis axis) {
- return persp->tmat.has_finite_image(axis);
+persp3d_VP_is_finite (Persp3DImpl *persp_impl, Proj::Axis axis) {
+ return persp_impl->tmat.has_finite_image(axis);
}
void
persp3d_toggle_VP (Persp3D *persp, Proj::Axis axis, bool set_undo) {
- persp->tmat.toggle_finite(axis);
+ persp->perspective_impl->tmat.toggle_finite(axis);
// FIXME: Remove this repr update and rely on vp_drag_sel_modified() to do this for us
// On the other hand, vp_drag_sel_modified() would update all boxes;
// here we can confine ourselves to the boxes of this particular perspective.
void
persp3d_set_VP_state (Persp3D *persp, Proj::Axis axis, Proj::VPState state) {
- if (persp3d_VP_is_finite(persp, axis) != (state == Proj::VP_FINITE)) {
+ if (persp3d_VP_is_finite(persp->perspective_impl, axis) != (state == Proj::VP_FINITE)) {
persp3d_toggle_VP(persp, axis);
}
}
void
persp3d_rotate_VP (Persp3D *persp, Proj::Axis axis, double angle, bool alt_pressed) { // angle is in degrees
// FIXME: Most of this functionality should be moved to trans_mat_3x4.(h|cpp)
- if (persp->tmat.has_finite_image(axis)) {
+ if (persp->perspective_impl->tmat.has_finite_image(axis)) {
// don't rotate anything for finite VPs
return;
}
- Proj::Pt2 v_dir_proj (persp->tmat.column(axis));
+ Proj::Pt2 v_dir_proj (persp->perspective_impl->tmat.column(axis));
Geom::Point v_dir (v_dir_proj[0], v_dir_proj[1]);
double a = Geom::atan2 (v_dir) * 180/M_PI;
a += alt_pressed ? 0.5 * ((angle > 0 ) - (angle < 0)) : angle; // the r.h.s. yields +/-0.5 or angle
- persp->tmat.set_infinite_direction (axis, a);
+ persp->perspective_impl->tmat.set_infinite_direction (axis, a);
persp3d_update_box_reprs (persp);
SP_OBJECT(persp)->updateRepr(SP_OBJECT_WRITE_EXT);
}
void
-persp3d_update_with_point (Persp3D *persp, Proj::Axis const axis, Proj::Pt2 const &new_image) {
- persp->tmat.set_image_pt (axis, new_image);
+persp3d_update_with_point (Persp3DImpl *persp_impl, Proj::Axis const axis, Proj::Pt2 const &new_image) {
+ persp_impl->tmat.set_image_pt (axis, new_image);
}
void
persp3d_apply_affine_transformation (Persp3D *persp, Geom::Matrix const &xform) {
- persp->tmat *= xform;
+ persp->perspective_impl->tmat *= xform;
persp3d_update_box_reprs(persp);
SP_OBJECT(persp)->updateRepr(SP_OBJECT_WRITE_EXT);
}
gchar *
-persp3d_pt_to_str (Persp3D *persp, Proj::Axis const axis)
+persp3d_pt_to_str (Persp3DImpl *persp_impl, Proj::Axis const axis)
{
- return persp->tmat.pt_to_str(axis);
+ return persp_impl->tmat.pt_to_str(axis);
}
void
persp3d_add_box (Persp3D *persp, SPBox3D *box) {
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
if (!box) {
return;
}
- if (std::find (persp->boxes.begin(), persp->boxes.end(), box) != persp->boxes.end()) {
+ if (std::find (persp_impl->boxes.begin(), persp_impl->boxes.end(), box) != persp_impl->boxes.end()) {
return;
}
- persp->boxes.push_back(box);
+ persp_impl->boxes.push_back(box);
}
void
persp3d_remove_box (Persp3D *persp, SPBox3D *box) {
- std::vector<SPBox3D *>::iterator i = std::find (persp->boxes.begin(), persp->boxes.end(), box);
- if (i != persp->boxes.end()) {
- persp->boxes.erase(i);
- }
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
+ std::vector<SPBox3D *>::iterator i = std::find (persp_impl->boxes.begin(), persp_impl->boxes.end(), box);
+ if (i != persp_impl->boxes.end())
+ persp_impl->boxes.erase(i);
}
bool
persp3d_has_box (Persp3D *persp, SPBox3D *box) {
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
// FIXME: For some reason, std::find() does not seem to compare pointers "correctly" (or do we need to
// provide a proper comparison function?), so we manually traverse the list.
- for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) {
+ for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) {
if ((*i) == box) {
return true;
}
void
persp3d_add_box_transform (Persp3D *persp, SPBox3D *box) {
- std::map<SPBox3D *, bool>::iterator i = persp->boxes_transformed->find(box);
- if (i != persp->boxes_transformed->end() && (*i).second == true) {
- g_print ("Warning! In %s (%d): trying to add transform status for box %d twice when it's already listed as true.\n", SP_OBJECT_REPR(persp)->attribute("id"), persp->my_counter, box->my_counter);
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
+ std::map<SPBox3D *, bool>::iterator i = persp_impl->boxes_transformed->find(box);
+ if (i != persp_impl->boxes_transformed->end() && (*i).second == true) {
+ g_print ("Warning! In %s (%d): trying to add transform status for box %d twice when it's already listed as true.\n", SP_OBJECT_REPR(persp_impl)->attribute("id"), persp_impl->my_counter, box->my_counter);
return;
}
- (*persp->boxes_transformed)[box] = false;
+ (*persp_impl->boxes_transformed)[box] = false;
}
void
persp3d_remove_box_transform (Persp3D *persp, SPBox3D *box) {
- persp->boxes_transformed->erase(box);
+ persp->perspective_impl->boxes_transformed->erase(box);
}
void
persp3d_set_box_transformed (Persp3D *persp, SPBox3D *box, bool transformed) {
- if (persp->boxes_transformed->find(box) == persp->boxes_transformed->end()) {
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
+ if (persp_impl->boxes_transformed->find(box) == persp_impl->boxes_transformed->end()) {
g_print ("Warning! In %s (%d): trying to set transform status for box %d, but it is not listed in the perspective!! Aborting.\n",
- SP_OBJECT_REPR(persp)->attribute("id"), persp->my_counter,
+ SP_OBJECT_REPR(persp)->attribute("id"), persp_impl->my_counter,
box->my_counter);
return;
}
- (*persp->boxes_transformed)[box] = transformed;
+ (*persp_impl->boxes_transformed)[box] = transformed;
}
bool
persp3d_was_transformed (Persp3D *persp) {
- if (persp->boxes_transformed->size() == 1) {
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
+ if (persp_impl->boxes_transformed->size() == 1) {
/* either the transform has not been applied to the single box associated to this perspective yet
or the transform was already reset; in both cases we need to return false because upcoming
transforms need to be applied */
- (*persp->boxes_transformed->begin()).second = false; // make sure the box is marked as untransformed (in case more boxes are added later)
+ (*persp_impl->boxes_transformed->begin()).second = false; // make sure the box is marked as untransformed (in case more boxes are added later)
return false;
}
- for (std::map<SPBox3D *, bool>::iterator i = persp->boxes_transformed->begin();
- i != persp->boxes_transformed->end(); ++i) {
+ for (std::map<SPBox3D *, bool>::iterator i = persp_impl->boxes_transformed->begin();
+ i != persp_impl->boxes_transformed->end(); ++i) {
if ((*i).second == true) {
// at least one of the boxes in the perspective has already been transformed;
return true;
bool
persp3d_all_transformed(Persp3D *persp) {
- for (std::map<SPBox3D *, bool>::iterator i = persp->boxes_transformed->begin();
- i != persp->boxes_transformed->end(); ++i) {
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
+ for (std::map<SPBox3D *, bool>::iterator i = persp_impl->boxes_transformed->begin();
+ i != persp_impl->boxes_transformed->end(); ++i) {
if ((*i).second == false) {
return false;
}
void
persp3d_unset_transforms(Persp3D *persp) {
- for (std::map<SPBox3D *, bool>::iterator i = persp->boxes_transformed->begin();
- i != persp->boxes_transformed->end(); ++i) {
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
+ for (std::map<SPBox3D *, bool>::iterator i = persp_impl->boxes_transformed->begin();
+ i != persp_impl->boxes_transformed->end(); ++i) {
(*i).second = false;
}
}
void
persp3d_update_box_displays (Persp3D *persp) {
- if (persp->boxes.empty())
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
+ if (persp_impl->boxes.empty())
return;
- for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) {
+ for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) {
box3d_position_set(*i);
}
}
void
persp3d_update_box_reprs (Persp3D *persp) {
- if (persp->boxes.empty())
+ if (!persp) {
+ // Hmm, is it an error if this happens?
return;
- for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) {
+ }
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
+ if (persp_impl->boxes.empty())
+ return;
+ for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) {
SP_OBJECT(*i)->updateRepr(SP_OBJECT_WRITE_EXT);
box3d_set_z_orders(*i);
}
void
persp3d_update_z_orders (Persp3D *persp) {
- if (persp->boxes.empty())
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
+ if (persp_impl->boxes.empty())
return;
- for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) {
+ for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) {
box3d_set_z_orders(*i);
}
}
// obsolete. We should do this.
std::list<SPBox3D *>
persp3d_list_of_boxes(Persp3D *persp) {
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
std::list<SPBox3D *> bx_lst;
- for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) {
+ for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) {
bx_lst.push_back(*i);
}
return bx_lst;
bool
persp3d_perspectives_coincide(const Persp3D *lhs, const Persp3D *rhs)
{
- return lhs->tmat == rhs->tmat;
+ return lhs->perspective_impl->tmat == rhs->perspective_impl->tmat;
}
void
/* checks whether all boxes linked to this perspective are currently selected */
bool
persp3d_has_all_boxes_in_selection (Persp3D *persp) {
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+
std::list<SPBox3D *> selboxes = sp_desktop_selection(inkscape_active_desktop())->box3DList();
- for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) {
+ for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) {
if (std::find(selboxes.begin(), selboxes.end(), *i) == selboxes.end()) {
// we have an unselected box in the perspective
return false;
// for all perspectives in the list ...
for (i = plist.begin(); i != plist.end(); ++i) {
Persp3D *persp = *i;
+ Persp3DImpl *persp_impl = persp->perspective_impl;
// ... and each box associated to it ...
- for (j = persp->boxes.begin(); j != persp->boxes.end(); ++j) {
+ for (j = persp_impl->boxes.begin(); j != persp_impl->boxes.end(); ++j) {
SPBox3D *box = *j;
// ... check whether it is unselected, and if so add it to the list
- if (persp->boxes_transformed->find(box) == persp->boxes_transformed->end()) {
+ if (persp_impl->boxes_transformed->find(box) == persp_impl->boxes_transformed->end()) {
punsel[persp].push_back(box);
}
}
@@ -620,7 +664,8 @@ persp3d_split_perspectives_according_to_selection(Inkscape::Selection *selection
// ... if the perspective has unselected boxes ...
if (!(*i).second.empty()) {
// create a new perspective and move these boxes over
- Persp3D * new_persp = persp3d_create_xml_element (SP_OBJECT_DOCUMENT(persp), persp);
+ SPDocument *document = SP_OBJECT_DOCUMENT(persp);
+ Persp3D * new_persp = persp3d_create_xml_element (document, persp->perspective_impl);
for (j = (*i).second.begin(); j != (*i).second.end(); ++j) {
SPBox3D *box = *j;
box3d_switch_perspectives(box, persp, new_persp);
@@ -633,7 +678,8 @@ persp3d_split_perspectives_according_to_selection(Inkscape::Selection *selection
void
persp3d_print_debugging_info (Persp3D *persp) {
- g_print ("=== Info for Persp3D %d ===\n", persp->my_counter);
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+ g_print ("=== Info for Persp3D %d ===\n", persp_impl->my_counter);
gchar * cstr;
for (int i = 0; i < 4; ++i) {
cstr = persp3d_get_VP(persp, Proj::axes[i]).coord_string();
g_free(cstr);
g_print (" Boxes: ");
- for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) {
- g_print ("%d (%d) ", (*i)->my_counter, box3d_get_perspective(*i)->my_counter);
+ for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) {
+ g_print ("%d (%d) ", (*i)->my_counter, box3d_get_perspective(*i)->perspective_impl->my_counter);
}
g_print ("\n");
g_print ("========================\n");
for (std::list<Persp3D *>::iterator j = sel_persps.begin(); j != sel_persps.end(); ++j) {
Persp3D *persp = SP_PERSP3D(*j);
- g_print (" %s (%d): ", SP_OBJECT_REPR(persp)->attribute("id"), persp->my_counter);
- for (std::map<SPBox3D *, bool>::iterator i = persp->boxes_transformed->begin();
- i != persp->boxes_transformed->end(); ++i) {
+ Persp3DImpl *persp_impl = persp->perspective_impl;
+ g_print (" %s (%d): ", SP_OBJECT_REPR(persp)->attribute("id"), persp->perspective_impl->my_counter);
+ for (std::map<SPBox3D *, bool>::iterator i = persp_impl->boxes_transformed->begin();
+ i != persp_impl->boxes_transformed->end(); ++i) {
g_print ("<%d,%d> ", (*i).first->my_counter, (*i).second);
}
g_print ("\n");
g_print ("======================================\n\n");
}
+void print_current_persp3d(gchar *func_name, Persp3D *persp) {
+ g_print ("%s: current_persp3d is now %s\n",
+ func_name,
+ persp ? SP_OBJECT_REPR(persp)->attribute("id") : "NULL");
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/persp3d.h b/src/persp3d.h
index 79bec0232c5372465266a04e90924ade2e8e1481..31a6212c7a9a9b2e5bb4805992a464408dc3e580 100644 (file)
--- a/src/persp3d.h
+++ b/src/persp3d.h
class SPBox3D;
class Box3DContext;
-struct Persp3D : public SPObject {
+class Persp3DImpl {
+public:
+ Persp3DImpl();
+ ~Persp3DImpl();
+
+//private:
Proj::TransfMat3x4 tmat;
// Also write the list of boxes into the xml repr and vice versa link boxes to their persp3d?
// for debugging only
int my_counter;
+
+// friend class Persp3D;
+};
+
+struct Persp3D : public SPObject {
+ Persp3DImpl *perspective_impl;
};
struct Persp3DClass {
return SP_PERSP3D(SP_ACTIVE_DOCUMENT->getObjectByRepr(repr));
}
inline Proj::Pt2 persp3d_get_VP (Persp3D *persp, Proj::Axis axis) {
- return persp->tmat.column(axis);
+ return persp->perspective_impl->tmat.column(axis);
}
Geom::Point persp3d_get_PL_dir_from_pt (Persp3D *persp, Geom::Point const &pt, Proj::Axis axis); // convenience wrapper around the following two
Geom::Point persp3d_get_finite_dir (Persp3D *persp, Geom::Point const &pt, Proj::Axis axis);
Geom::Point persp3d_get_infinite_dir (Persp3D *persp, Proj::Axis axis);
double persp3d_get_infinite_angle (Persp3D *persp, Proj::Axis axis);
-bool persp3d_VP_is_finite (Persp3D *persp, Proj::Axis axis);
+bool persp3d_VP_is_finite (Persp3DImpl *persp_impl, Proj::Axis axis);
void persp3d_toggle_VP (Persp3D *persp, Proj::Axis axis, bool set_undo = true);
void persp3d_toggle_VPs (std::list<Persp3D *>, Proj::Axis axis);
void persp3d_set_VP_state (Persp3D *persp, Proj::Axis axis, Proj::VPState state);
void persp3d_rotate_VP (Persp3D *persp, Proj::Axis axis, double angle, bool alt_pressed); // angle is in degrees
-void persp3d_update_with_point (Persp3D *persp, Proj::Axis const axis, Proj::Pt2 const &new_image);
void persp3d_apply_affine_transformation (Persp3D *persp, Geom::Matrix const &xform);
-gchar * persp3d_pt_to_str (Persp3D *persp, Proj::Axis const axis);
void persp3d_add_box (Persp3D *persp, SPBox3D *box);
void persp3d_remove_box (Persp3D *persp, SPBox3D *box);
void persp3d_update_box_displays (Persp3D *persp);
void persp3d_update_box_reprs (Persp3D *persp);
void persp3d_update_z_orders (Persp3D *persp);
-inline unsigned int persp3d_num_boxes (Persp3D *persp) { return persp->boxes.size(); }
+inline unsigned int persp3d_num_boxes (Persp3D *persp) { return persp->perspective_impl->boxes.size(); }
std::list<SPBox3D *> persp3d_list_of_boxes(Persp3D *persp);
bool persp3d_perspectives_coincide(const Persp3D *lhs, const Persp3D *rhs);
void persp3d_absorb(Persp3D *persp1, Persp3D *persp2);
-Persp3D * persp3d_create_xml_element (SPDocument *document, Persp3D *dup = NULL);
+Persp3D * persp3d_create_xml_element (SPDocument *document, Persp3DImpl *dup = NULL);
Persp3D * persp3d_document_first_persp (SPDocument *document);
bool persp3d_has_all_boxes_in_selection (Persp3D *persp);
void persp3d_print_debugging_info_all(SPDocument *doc);
void persp3d_print_all_selected();
+/* Internally used functions; maybe these should be made more private? */
+void persp3d_update_with_point (Persp3DImpl *persp_impl, Proj::Axis const axis, Proj::Pt2 const &new_image);
+gchar * persp3d_pt_to_str (Persp3DImpl *persp_impl, Proj::Axis const axis);
+
+void print_current_persp3d(gchar *func_name, Persp3D *persp);
+
#endif /* __PERSP3D_H__ */
/*
diff --git a/src/selection.cpp b/src/selection.cpp
index 4d92a18df77948f7de0620a8609566eb9e33075e..ed8a9d57b86034dfcaf4c36915bace17a5ff3671 100644 (file)
--- a/src/selection.cpp
+++ b/src/selection.cpp
Persp3D *persp = box3d_get_perspective(box);
std::map<Persp3D *, unsigned int>::iterator p = _persps.find(persp);
if (p == _persps.end()) {
- g_print ("Warning! Trying to remove unselected perspective from selection!\n");
+ //g_print ("Warning! Trying to remove unselected perspective from selection!\n");
return;
}
if ((*p).second > 1) {
index ab46b21a6c955ee8c69fead5af637fa15cad043d..78ceec4671178a2bf4fb33535d7f0137eeab7af4 100644 (file)
--- a/src/vanishing-point.cpp
+++ b/src/vanishing-point.cpp
@@ -103,7 +103,7 @@ vp_knot_moved_handler (SPKnot */*knot*/, Geom::Point const *ppointer, guint stat
sel_boxes = (*vp)->selectedBoxes(sp_desktop_selection(inkscape_active_desktop()));
// we create a new perspective ...
- Persp3D *new_persp = persp3d_create_xml_element (dragger->parent->document, old_persp);
+ Persp3D *new_persp = persp3d_create_xml_element (dragger->parent->document, old_persp->perspective_impl);
/* ... unlink the boxes from the old one and
FIXME: We need to unlink the _un_selected boxes of each VP so that
void
VanishingPoint::set_pos(Proj::Pt2 const &pt) {
g_return_if_fail (_persp);
- _persp->tmat.set_image_pt (_axis, pt);
+ _persp->perspective_impl->tmat.set_image_pt (_axis, pt);
}
std::list<SPBox3D *>
index 4362139464d0921768721fc4a5aef0d730ba076c..48e22d53f2895d742f6807836f8de9ba11eddfe1 100644 (file)
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
// TODO: Take all selected perspectives into account but don't touch the state button if not all of them
// have the same state (otherwise a call to box3d_vp_z_state_changed() is triggered and the states
// are reset).
- bool is_infinite = !persp3d_VP_is_finite(persp, axis);
+ bool is_infinite = !persp3d_VP_is_finite(persp->perspective_impl, axis);
if (is_infinite) {
gtk_toggle_action_set_active(tact, TRUE);
GtkAction *act = 0;
GtkToggleAction *tact = 0;
Persp3D *persp = persp3d_get_from_repr(persp_repr);
+ if (!persp) {
+ // Hmm, is it an error if this happens?
+ return;
+ }
{
adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_x"));
act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x_action"));
sp_repr_synthesize_events(persp_repr, &box3d_persp_tb_repr_events, tbl);
}
- inkscape_active_document()->current_persp3d = persp3d_get_from_repr(persp_repr);
+ inkscape_active_document()->setCurrentPersp3D(persp3d_get_from_repr(persp_repr));
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setString("/tools/shapes/3dbox/persp", persp_repr->attribute("id"));
@@ -3364,7 +3368,6 @@ box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis ax
// in turn, prevent listener from responding
g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE));
- //Persp3D *persp = document->current_persp3d;
std::list<Persp3D *> sel_persps = sp_desktop_selection(desktop)->perspList();
if (sel_persps.empty()) {
// this can happen when the document is created; we silently ignore it
@@ -3372,7 +3375,7 @@ box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis ax
}
Persp3D *persp = sel_persps.front();
- persp->tmat.set_infinite_direction (axis, adj->value);
+ persp->perspective_impl->tmat.set_infinite_direction (axis, adj->value);
SP_OBJECT(persp)->updateRepr();
// TODO: use the correct axis here, too
@@ -3435,7 +3438,7 @@ static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions,
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
EgeAdjustmentAction* eact = 0;
SPDocument *document = sp_desktop_document (desktop);
- Persp3D *persp = document->current_persp3d;
+ Persp3DImpl *persp_impl = document->getCurrentPersp3DImpl();
EgeAdjustmentAction* box3d_angle_x = 0;
EgeAdjustmentAction* box3d_angle_y = 0;
@@ -3459,7 +3462,7 @@ static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions,
box3d_angle_x = eact;
}
- if (!persp3d_VP_is_finite(persp, Proj::X)) {
+ if (!persp3d_VP_is_finite(persp_impl, Proj::X)) {
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
} else {
gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
@@ -3499,7 +3502,7 @@ static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions,
box3d_angle_y = eact;
}
- if (!persp3d_VP_is_finite(persp, Proj::Y)) {
+ if (!persp3d_VP_is_finite(persp_impl, Proj::Y)) {
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
} else {
gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
@@ -3538,7 +3541,7 @@ static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions,
box3d_angle_z = eact;
}
- if (!persp3d_VP_is_finite(persp, Proj::Z)) {
+ if (!persp3d_VP_is_finite(persp_impl, Proj::Z)) {
gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
} else {
gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
}
+/*
class PencilToleranceObserver : public Inkscape::Preferences::Observer {
public:
PencilToleranceObserver(Glib::ustring const &path, GObject *x) : Observer(path), _obj(x)
private:
GObject *_obj;
};
-
+*/
static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
{
@@ -4040,9 +4044,6 @@ static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio
1, 2);
ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
-
- PencilToleranceObserver *obs =
- new PencilToleranceObserver("/tools/freehand/pencil/tolerance", G_OBJECT(holder));
}
/* advanced shape options */
@@ -6218,7 +6219,7 @@ sp_text_toolbox_selection_modified (Inkscape::Selection *selection, guint /*flag
}
void
-sp_text_toolbox_subselection_changed (gpointer /*dragger*/, GObject *tbl)
+sp_text_toolbox_subselection_changed (gpointer /*tc*/, GObject *tbl)
{
sp_text_toolbox_selection_changed (NULL, tbl);
}