Code

1ad910bfad249cd102f31bd320f4380ec2bbcda6
[inkscape.git] / src / perspective3d.cpp
1 #define __PERSPECTIVE3D_C__
3 /*
4  * Class modelling a 3D perspective
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-context.h"
15 #include "perspective-line.h"
16 #include <iostream>
17 #include "desktop.h"
19 // can probably be removed later
20 #include "inkscape.h"
22 namespace Box3D {
24 Perspective3D *
25 get_persp_of_box (const SP3DBox *box)
26 {
27     SPDesktop *desktop = inkscape_active_desktop(); // Should we pass the desktop as an argument?
28     for (GSList *p = desktop->perspectives; p != NULL; p = p->next) {
29         if (((Perspective3D *) p->data)->has_box (box))
30             return (Perspective3D *) p->data;
31     }
32     g_warning ("Stray 3D box!\n");
33     g_assert_not_reached();
34 }
36 /**
37  * Computes the intersection of the two perspective lines from pt1 and pt2 to the respective
38  * vanishing points in the given directions.
39  */
40 // FIXME: This has been moved to a virtual method inside PerspectiveLine; can probably be purged
41 NR::Point
42 perspective_intersection (NR::Point pt1, Box3D::Axis dir1, NR::Point pt2, Box3D::Axis dir2, Perspective3D *persp)
43 {
44     VanishingPoint const *vp1 = persp->get_vanishing_point(dir1);
45     VanishingPoint const *vp2 = persp->get_vanishing_point(dir2);
46     NR::Maybe<NR::Point> meet = Line(pt1, *vp1).intersect(Line(pt2, *vp2));
47     // FIXME: How to handle parallel lines (also depends on the type of the VPs)?
48     if (!meet) { meet = NR::Point (0.0, 0.0); }
49     return *meet;
50 }
52 /**
53  * Find the point on the perspective line from line_pt to the
54  * vanishing point in direction dir that is closest to ext_pt.
55  */
56 NR::Point
57 perspective_line_snap (NR::Point line_pt, Box3D::Axis dir, NR::Point ext_pt, Perspective3D *persp)
58 {
59     return PerspectiveLine(line_pt, dir, persp).closest_to(ext_pt);
60 }  
62 Perspective3D::Perspective3D (VanishingPoint const &pt_x, VanishingPoint const &pt_y, VanishingPoint const &pt_z)
63     : desktop (NULL),
64       vp_x (pt_x),
65       vp_y (pt_y),
66       vp_z (pt_z),
67       boxes (NULL)
68 {
69 }
71 Perspective3D::~Perspective3D ()
72 {
73     g_assert (desktop != NULL);
74     desktop->remove_perspective (this);
76     g_slist_free (boxes);
77 }
80 VanishingPoint *
81 Perspective3D::get_vanishing_point (Box3D::Axis const dir)
82 {
83     // FIXME: Also handle value 'NONE' in switch
84     switch (dir) {
85         case X:
86             return &vp_x;
87             break;
88         case Y:
89             return &vp_y;
90             break;
91         case Z:
92             return &vp_z;
93             break;
94     }
95 }
97 void
98 Perspective3D::set_vanishing_point (Box3D::Axis const dir, VanishingPoint const &pt)
99 {
100     switch (dir) {
101         case X:
102             vp_x = pt;
103             break;
104         case Y:
105             vp_y = pt;
106             break;
107         case Z:
108             vp_z = pt;
109             break;
110         case NONE:
111             // no vanishing point to set
112             break;
113     }
116 void
117 Perspective3D::add_box (SP3DBox *box)
119     if (g_slist_find (this->boxes, box) != NULL) {
120         // Don't add the same box twice
121         g_warning ("Box already uses the current perspective. We don't add it again.\n");
122         return;
123     }
124     this->boxes = g_slist_append (this->boxes, box);
127 void
128 Perspective3D::remove_box (const SP3DBox *box)
130     if (!g_slist_find (this->boxes, box)) {
131         g_warning ("Could not find box that is to be removed in the current perspective.\n");
132     }
133     this->boxes = g_slist_remove (this->boxes, box);
136 bool
137 Perspective3D::has_box (const SP3DBox *box)
139     return (g_slist_find (this->boxes, box) != NULL);
142 } // namespace Box3D 
143  
144 /*
145   Local Variables:
146   mode:c++
147   c-file-style:"stroustrup"
148   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
149   indent-tabs-mode:nil
150   fill-column:99
151   End:
152 */
153 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :