Code

More meaningful name for 3D axis directions
[inkscape.git] / src / box3d-face.cpp
1 #define __SP_3DBOX_FACE_C__
3 /*
4  * Face of a 3D box ('perspectivic rectangle')
5  *
6  * Authors:
7  *   Maximilian Albert <Anhalter42@gmx.de>
8  *
9  * Copyright (C) 2007  authors
10  *
11  * Released under GNU GPL, read the file 'COPYING' for more information
12  */
14 #include "box3d-face.h"
15 #include <iostream>
17 Box3DFace::Box3DFace(SP3DBox *box3d) : dir1 (Box3D::NONE), dir2 (Box3D::NONE), path (NULL), parent_box3d (box3d)
18 {
19     for (int i = 0; i < 4; ++i) {
20         this->corners[i] = NR::Point(0, 0);
21     }
22
24 void Box3DFace::set_shape(NR::Point const ul, NR::Point const lr,
25                      Box3D::Axis const dir1, Box3D::Axis const dir2,
26                      unsigned int shift_count, NR::Maybe<NR::Point> pt_align, bool align_along_PL)
27 {
28     corners[0] = ul;
29     if (!pt_align) {
30         corners[2] = lr;
31     } else {
32         if (align_along_PL) {
33             Box3D::Axis dir3 = Box3D::third_axis_direction (dir1, dir2);
34             Box3D::Line line1(*SP3DBoxContext::current_perspective->get_vanishing_point(dir1), lr);
35             Box3D::Line line2(*pt_align, *SP3DBoxContext::current_perspective->get_vanishing_point(dir3));
36             corners[2] = *line1.intersect(line2);
37         } else {
38             corners[2] = Box3D::Line(*pt_align, *SP3DBoxContext::current_perspective->get_vanishing_point(dir1)).closest_to(lr);
39         }
40     }
42     Box3D::PerspectiveLine first_line  (corners[0], dir1);
43     Box3D::PerspectiveLine second_line (corners[2], dir2);
44     NR::Maybe<NR::Point> ur = first_line.intersect(second_line);
46     Box3D::PerspectiveLine third_line  (corners[0], dir2);
47     Box3D::PerspectiveLine fourth_line (corners[2], dir1);
48     NR::Maybe<NR::Point> ll = third_line.intersect(fourth_line);
50     // FIXME: How to handle the case if one of the intersections doesn't exist?
51     //        Maybe set them equal to the corresponding VPs? 
52     if (!ur) ur = NR::Point(0.0, 0.0);    
53     if (!ll) ll = NR::Point(0.0, 0.0);
55     corners[1] = *ll;
56     corners[3] = *ur;
58     this->dir1 = dir1;
59     this->dir2 = dir2;
61     // FIXME: Can be made more concise
62     NR::Point tmp_pt;
63     for (unsigned int i=0; i < shift_count; i++) {
64         tmp_pt = corners[3];
65         corners[1] = corners[0];
66         corners[2] = corners[1];
67         corners[3] = corners[2];
68         corners[0] = tmp_pt;
69     }
70 }
72 Box3DFace::Box3DFace(Box3DFace const &box3dface)
73 {
74     for (int i = 0; i < 4; ++i) {
75         this->corners[i] = box3dface.corners[i];
76     }
77     this->dir1 = box3dface.dir1;
78     this->dir2 = box3dface.dir2;
79 }
81 NR::Point Box3DFace::operator[](unsigned int i)
82 {
83     return corners[i % 4];
84 }
86 /**
87  * Append the curve's path as a child to the given 3D box (since SP3DBox
88  * is derived from SPGroup, so we can append children to its svg representation)
89  */
90 void Box3DFace::hook_path_to_3dbox()
91 {
92     SPDesktop *desktop = inkscape_active_desktop();
93     Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_EVENT_CONTEXT_DOCUMENT(inkscape_active_event_context()));
94     Inkscape::XML::Node *repr_face = xml_doc->createElement("svg:path");
95     sp_desktop_apply_style_tool (desktop, repr_face, "tools.shapes.3dbox", false);
96     this->path = SP_PATH(SP_OBJECT(parent_box3d)->appendChildRepr(repr_face));
97     Inkscape::GC::release(repr_face);
98 }
100 /**
101  * Write the path's "d" attribute to the SVG representation.
102  */
103 void Box3DFace::set_path_repr()
105     SP_OBJECT(this->path)->repr->setAttribute("d", svg_repr_string());
108 void Box3DFace::set_curve()
110     SPDocument *doc = SP_OBJECT_DOCUMENT(this->parent_box3d);
111     gdouble height = sp_document_height(doc);
113     SPCurve *curve = sp_curve_new();
114     sp_curve_moveto(curve, corners[0][NR::X], height - corners[0][NR::Y]);
115     sp_curve_lineto(curve, corners[1][NR::X], height - corners[1][NR::Y]);
116     sp_curve_lineto(curve, corners[2][NR::X], height - corners[2][NR::Y]);
117     sp_curve_lineto(curve, corners[3][NR::X], height - corners[3][NR::Y]);
118     sp_curve_closepath(curve);
119     sp_shape_set_curve(SP_SHAPE(this->path), curve, true);
120     sp_curve_unref(curve);
123 gchar * Box3DFace::svg_repr_string()
125     SPDocument *doc = SP_OBJECT_DOCUMENT(this->parent_box3d);
126     gdouble height = sp_document_height(doc);
128     GString *pstring = g_string_new("");
129     g_string_sprintf (pstring, "M %f,%f L %f,%f L %f,%f L %f,%f z",
130                                corners[0][NR::X], height - corners[0][NR::Y],
131                                corners[1][NR::X], height - corners[1][NR::Y],
132                                corners[2][NR::X], height - corners[2][NR::Y],
133                                corners[3][NR::X], height - corners[3][NR::Y]);
134     return pstring->str;
137 /*
138   Local Variables:
139   mode:c++
140   c-file-style:"stroustrup"
141   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
142   indent-tabs-mode:nil
143   fill-column:99
144   End:
145 */
146 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :