Welcome to mirror list, hosted at ThFree Co, Russian Federation.

OccluderSource.cpp « view_map « intern « freestyle « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 378b017b504d1f5ce28a65681fd142244f4bfc18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* SPDX-License-Identifier: GPL-2.0-or-later */

/** \file
 * \ingroup freestyle
 * \brief Class to define a cell grid surrounding the projected image of a scene
 */

#include <algorithm>

#include "OccluderSource.h"

#include "BKE_global.h"

namespace Freestyle {

OccluderSource::OccluderSource(const GridHelpers::Transform &t, WingedEdge &we)
    : wingedEdge(we), valid(false), transform(t)
{
  begin();
}

OccluderSource::~OccluderSource() = default;

void OccluderSource::buildCachedPolygon()
{
  vector<Vec3r> vertices(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()));
  // This doesn't work, because our functor's polymorphism won't survive the copy:
  // std::transform(vertices.begin(), vertices.end(), vertices.begin(), transform);
  // so we have to do:
  for (vector<Vec3r>::iterator i = vertices.begin(); i != vertices.end(); ++i) {
    (*i) = transform(*i);
  }
  cachedPolygon = Polygon3r(vertices, transform((*currentFace)->GetNormal()));
}

void OccluderSource::begin()
{
  vector<WShape *> &wshapes = wingedEdge.getWShapes();
  currentShape = wshapes.begin();
  shapesEnd = wshapes.end();
  valid = false;
  if (currentShape != shapesEnd) {
    vector<WFace *> &wFaces = (*currentShape)->GetFaceList();
    currentFace = wFaces.begin();
    facesEnd = wFaces.end();

    if (currentFace != facesEnd) {
      buildCachedPolygon();
      valid = true;
    }
  }
}

bool OccluderSource::next()
{
  if (valid) {
    ++currentFace;
    while (currentFace == facesEnd) {
      ++currentShape;
      if (currentShape == shapesEnd) {
        valid = false;
        return false;
      }

      vector<WFace *> &wFaces = (*currentShape)->GetFaceList();
      currentFace = wFaces.begin();
      facesEnd = wFaces.end();
    }
    buildCachedPolygon();
    return true;
  }
  return false;
}

bool OccluderSource::isValid()
{
  // Or:
  // return currentShapes != shapesEnd && currentFace != facesEnd;
  return valid;
}

WFace *OccluderSource::getWFace()
{
  return valid ? *currentFace : nullptr;
}

Polygon3r OccluderSource::getCameraSpacePolygon()
{
  return Polygon3r(GridHelpers::enumerateVertices((*currentFace)->getEdgeList()),
                   (*currentFace)->GetNormal());
}

Polygon3r &OccluderSource::getGridSpacePolygon()
{
  return cachedPolygon;
}

void OccluderSource::getOccluderProscenium(real proscenium[4])
{
  begin();
  const Vec3r &initialPoint = cachedPolygon.getVertices()[0];
  proscenium[0] = proscenium[1] = initialPoint[0];
  proscenium[2] = proscenium[3] = initialPoint[1];
  while (isValid()) {
    GridHelpers::expandProscenium(proscenium, cachedPolygon);
    next();
  }
  if (G.debug & G_DEBUG_FREESTYLE) {
    cout << "Proscenium: (" << proscenium[0] << ", " << proscenium[1] << ", " << proscenium[2]
         << ", " << proscenium[3] << ")" << endl;
  }
}

real OccluderSource::averageOccluderArea()
{
  real area = 0.0;
  unsigned numFaces = 0;
  for (begin(); isValid(); next()) {
    Vec3r min, max;
    cachedPolygon.getBBox(min, max);
    area += (max[0] - min[0]) * (max[1] - min[1]);
    ++numFaces;
  }
  area /= numFaces;
  return area;
}

} /* namespace Freestyle */