Merged changes in the trunk up to revision 44266 (including BMesh).
[blender.git] / source / blender / freestyle / intern / view_map / OccluderSource.cpp
1 //
2 //  Filename         : OccluderSource.h
3 //  Author(s)        : Alexander Beels
4 //  Purpose          : Class to define a cell grid surrounding
5 //                     the projected image of a scene
6 //  Date of creation : 2010-12-21
7 //
8 ///////////////////////////////////////////////////////////////////////////////
9
10
11 //
12 //  Copyright (C) : Please refer to the COPYRIGHT file distributed 
13 //   with this source distribution. 
14 //
15 //  This program is free software; you can redistribute it and/or
16 //  modify it under the terms of the GNU General Public License
17 //  as published by the Free Software Foundation; either version 2
18 //  of the License, or (at your option) any later version.
19 //
20 //  This program is distributed in the hope that it will be useful,
21 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
22 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 //  GNU General Public License for more details.
24 //
25 //  You should have received a copy of the GNU General Public License
26 //  along with this program; if not, write to the Free Software
27 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28 //
29 ///////////////////////////////////////////////////////////////////////////////
30
31 #include "OccluderSource.h"
32 #include <algorithm>
33
34 OccluderSource::OccluderSource (const GridHelpers::Transform& t, WingedEdge& we) : wingedEdge(we), valid(false), transform(t) {
35         begin();
36 }
37
38 OccluderSource::~OccluderSource() {
39 }
40
41 void OccluderSource::buildCachedPolygon() {
42         vector<Vec3r> vertices(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()));
43         // This doesn't work, because our functor's polymorphism won't survive the copy:
44         // std::transform(vertices.begin(), vertices.end(), vertices.begin(), transform);
45         // so we have to do:
46         for ( vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i ) {
47                 (*i) = transform(*i);
48         }
49         cachedPolygon = Polygon3r(vertices, transform((*currentFace)->GetNormal()));
50 }
51
52 void OccluderSource::begin() {
53         vector<WShape*>& wshapes = wingedEdge.getWShapes();
54         currentShape = wshapes.begin();
55         shapesEnd = wshapes.end();
56         valid = false;
57         if ( currentShape != shapesEnd ) {
58                 vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
59                 currentFace = wFaces.begin();
60                 facesEnd = wFaces.end();
61
62                 if ( currentFace != facesEnd ) {
63                         buildCachedPolygon();
64                         valid = true;
65                 }
66         }
67 }
68
69 bool OccluderSource::next() {
70         if ( valid ) {
71                 ++currentFace;
72                 while ( currentFace == facesEnd ) {
73                         ++currentShape;
74                         if ( currentShape == shapesEnd ) {
75                                 valid = false;
76                                 return false;
77                         } else {
78                                 vector<WFace*>& wFaces = (*currentShape)->GetFaceList();
79                                 currentFace = wFaces.begin();
80                                 facesEnd = wFaces.end();
81                         }
82                 }
83                 buildCachedPolygon();
84                 return true;
85         }
86         return false;
87 }
88
89 bool OccluderSource::isValid() {
90         // Or:
91         // return currentShapes != shapesEnd && currentFace != facesEnd;
92         return valid;
93 }
94
95 WFace* OccluderSource::getWFace() {
96         return valid ? *currentFace : NULL;
97 }
98
99 Polygon3r OccluderSource::getCameraSpacePolygon() {
100         return Polygon3r(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()), (*currentFace)->GetNormal());
101 }
102
103 Polygon3r& OccluderSource::getGridSpacePolygon() {
104         return cachedPolygon;
105 }
106
107 void OccluderSource::getOccluderProscenium(real proscenium[4]) {
108         begin();
109         const Vec3r& initialPoint = cachedPolygon.getVertices()[0];
110         proscenium[0] = proscenium[1] = initialPoint[0];
111         proscenium[2] = proscenium[3] = initialPoint[1];
112         while ( isValid() ) {
113                 GridHelpers::expandProscenium (proscenium, cachedPolygon);
114                 next();
115         }
116         cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2] << ", " << proscenium[3] << ")" << endl;
117 }
118
119 real OccluderSource::averageOccluderArea() {
120         real area = 0.0;
121         unsigned numFaces = 0;
122         for ( begin(); isValid(); next() ) {
123                 Vec3r min, max;
124                 cachedPolygon.getBBox(min, max);
125                 area += (max[0] - min[0]) * (max[1] - min[1]);
126                 ++numFaces;
127         }
128         area /= numFaces;
129         return area;
130 }
131
132