Blender V5.0
GridHelpers.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
11
12#include <vector>
13
14#include "FRS_freestyle.h"
15
16#include "GeomUtils.h"
17#include "Polygon.h"
18
20
21#include "MEM_guardedalloc.h"
22
23namespace Freestyle {
24
25namespace GridHelpers {
26
28template<class T> T closestPointToSegment(const T &P, const T &A, const T &B, real &distance)
29{
30 T AB, AP, BP;
31 AB = B - A;
32 AP = P - A;
33 BP = P - B;
34
35 real c1(AB * AP);
36 if (c1 <= 0) {
37 distance = AP.norm();
38 return A; // A is closest point
39 }
40
41 real c2(AB * AB);
42 if (c2 <= c1) {
43 distance = BP.norm();
44 return B; // B is closest point
45 }
46
47 real b = c1 / c2;
48 T Pb, PPb;
49 Pb = A + b * AB;
50 PPb = P - Pb;
51
52 distance = PPb.norm();
53 return Pb; // closest point lies on AB
54}
55
56inline Vec3r closestPointOnPolygon(const Vec3r &point, const Polygon3r &poly)
57{
58 // First cast a ray from the point onto the polygon plane
59 // If the ray intersects the polygon, then the intersection point
60 // is the closest point on the polygon
61 real t, u, v;
62 if (poly.rayIntersect(point, poly.getNormal(), t, u, v)) {
63 return point + poly.getNormal() * t;
64 }
65
66 // Otherwise, get the nearest point on each edge, and take the closest
69 point, poly.getVertices()[2], poly.getVertices()[0], distance);
70 for (uint i = 0; i < 2; ++i) {
71 real t;
72 Vec3r p = closestPointToSegment(point, poly.getVertices()[i], poly.getVertices()[i + 1], t);
73 if (t < distance) {
74 distance = t;
75 closest = p;
76 }
77 }
78 return closest;
79}
80
81inline real distancePointToPolygon(const Vec3r &point, const Polygon3r &poly)
82{
83 // First cast a ray from the point onto the polygon plane
84 // If the ray intersects the polygon, then the intersection point
85 // is the closest point on the polygon
86 real t, u, v;
87 if (poly.rayIntersect(point, poly.getNormal(), t, u, v)) {
88 return (t > 0.0) ? t : -t;
89 }
90
91 // Otherwise, get the nearest point on each edge, and take the closest
93 for (uint i = 0; i < 2; ++i) {
94 real t = GeomUtils::distPointSegment(point, poly.getVertices()[i], poly.getVertices()[i + 1]);
95 if (t < distance) {
96 distance = t;
97 }
98 }
99 return distance;
100}
101
103 public:
104 virtual ~Transform() = 0;
105 virtual Vec3r operator()(const Vec3r &point) const = 0;
106
107 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:GridHelpers:Transform")
108};
109
110inline bool insideProscenium(const real proscenium[4], const Polygon3r &polygon)
111{
112 // N.B. The bounding box check is redundant for inserting occluders into cells, because the cell
113 // selection code in insertOccluders has already guaranteed that the bounding boxes will overlap.
114 // First check the viewport edges, since they are the easiest case
115 // Check if the bounding box is entirely outside the proscenium
116 Vec3r bbMin, bbMax;
117 polygon.getBBox(bbMin, bbMax);
118 if (bbMax[0] < proscenium[0] || bbMin[0] > proscenium[1] || bbMax[1] < proscenium[2] ||
119 bbMin[1] > proscenium[3])
120 {
121 return false;
122 }
123
124 Vec3r boxCenter(proscenium[0] + (proscenium[1] - proscenium[0]) / 2.0,
125 proscenium[2] + (proscenium[3] - proscenium[2]) / 2.0,
126 0.0);
127 Vec3r boxHalfSize(
128 (proscenium[1] - proscenium[0]) / 2.0, (proscenium[3] - proscenium[2]) / 2.0, 1.0);
129 Vec3r triverts[3] = {
130 Vec3r(polygon.getVertices()[0][0], polygon.getVertices()[0][1], 0.0),
131 Vec3r(polygon.getVertices()[1][0], polygon.getVertices()[1][1], 0.0),
132 Vec3r(polygon.getVertices()[2][0], polygon.getVertices()[2][1], 0.0),
133 };
134 return GeomUtils::overlapTriangleBox(boxCenter, boxHalfSize, triverts);
135}
136
137inline vector<Vec3r> enumerateVertices(const vector<WOEdge *> &fedges)
138{
139 vector<Vec3r> points;
140 // Iterate over vertices, storing projections in points
141 for (vector<WOEdge *>::const_iterator woe = fedges.begin(), woend = fedges.end(); woe != woend;
142 woe++)
143 {
144 points.push_back((*woe)->GetaVertex()->GetVertex());
145 }
146
147 return points;
148}
149
150void getDefaultViewProscenium(real viewProscenium[4]);
151
152inline void expandProscenium(real proscenium[4], const Polygon3r &polygon)
153{
154 Vec3r bbMin, bbMax;
155 polygon.getBBox(bbMin, bbMax);
156
157 const real epsilon = 1.0e-6;
158
159 if (bbMin[0] <= proscenium[0]) {
160 proscenium[0] = bbMin[0] - epsilon;
161 }
162
163 if (bbMin[1] <= proscenium[2]) {
164 proscenium[2] = bbMin[1] - epsilon;
165 }
166
167 if (bbMax[0] >= proscenium[1]) {
168 proscenium[1] = bbMax[0] + epsilon;
169 }
170
171 if (bbMax[1] >= proscenium[3]) {
172 proscenium[3] = bbMax[1] + epsilon;
173 }
174}
175
176inline void expandProscenium(real proscenium[4], const Vec3r &point)
177{
178 const real epsilon = 1.0e-6;
179
180 if (point[0] <= proscenium[0]) {
181 proscenium[0] = point[0] - epsilon;
182 }
183
184 if (point[1] <= proscenium[2]) {
185 proscenium[2] = point[1] - epsilon;
186 }
187
188 if (point[0] >= proscenium[1]) {
189 proscenium[1] = point[0] + epsilon;
190 }
191
192 if (point[1] >= proscenium[3]) {
193 proscenium[3] = point[1] + epsilon;
194 }
195}
196
197}; // namespace GridHelpers
198
199} /* namespace Freestyle */
unsigned int uint
Various tools for geometry.
Read Guarded memory(de)allocation.
Class to define a polygon.
Classes to define a Winged Edge data structure.
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define A
bool closest(btVector3 &v)
bool rayIntersect(const Vec3r &orig, const Vec3r &dir, real &t, real &u, real &v, real epsilon=M_EPSILON) const
Definition Polygon.h:186
void getBBox(Point &min, Point &max) const
Definition Polygon.h:71
const vector< Point > & getVertices() const
Definition Polygon.h:66
virtual Vec3r operator()(const Vec3r &point) const =0
float distance(VecOp< float, D >, VecOp< float, D >) RET
#define B
bool overlapTriangleBox(const Vec3r &boxcenter, const Vec3r &boxhalfsize, const Vec3r triverts[3])
real distPointSegment(const T &P, const T &A, const T &B)
Definition GeomUtils.h:32
VecMat::Vec3< real > Vec3r
Definition Geom.h:30
void getDefaultViewProscenium(real viewProscenium[4])
void expandProscenium(real proscenium[4], const Polygon3r &polygon)
real distancePointToPolygon(const Vec3r &point, const Polygon3r &poly)
Definition GridHelpers.h:81
T closestPointToSegment(const T &P, const T &A, const T &B, real &distance)
Definition GridHelpers.h:28
bool insideProscenium(const real proscenium[4], const Polygon3r &polygon)
Vec3r closestPointOnPolygon(const Vec3r &point, const Polygon3r &poly)
Definition GridHelpers.h:56
vector< Vec3r > enumerateVertices(const vector< WOEdge * > &fedges)
inherits from class Rep
Definition AppCanvas.cpp:20
double real
Definition Precision.h:14
i
Definition text_draw.cc:230