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