Files
test2/source/blender/freestyle/intern/geometry/GridHelpers.h
Jacques Lucke 64a9260921 Core: remove WITH_CXX_GUARDEDALLOC option
This implements the proposal from #124512. For that it contains the following
changes:
* Remove the global override of `new`/`delete` when `WITH_CXX_GUARDEDALLOC` was
  enabled.
* Always use `MEM_CXX_CLASS_ALLOC_FUNCS` where it is currently used. This used
  to be guarded by `WITH_CXX_GUARDEDALLOC` in some but not all cases. This means
  that a few classes which didn't use our guarded allocator by default before,
  are now using it.

Pull Request: https://projects.blender.org/blender/blender/pulls/130181
2024-11-13 13:39:49 +01:00

200 lines
5.2 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup freestyle
* \brief Class to define a cell grid surrounding the projected image of a scene
*/
#include <vector>
#include "FRS_freestyle.h"
#include "GeomUtils.h"
#include "Polygon.h"
#include "../winged_edge/WEdge.h"
#include "MEM_guardedalloc.h"
namespace Freestyle {
namespace GridHelpers {
/** Computes the distance from a point P to a segment AB */
template<class T> T closestPointToSegment(const T &P, const T &A, const T &B, real &distance)
{
T AB, AP, BP;
AB = B - A;
AP = P - A;
BP = P - B;
real c1(AB * AP);
if (c1 <= 0) {
distance = AP.norm();
return A; // A is closest point
}
real c2(AB * AB);
if (c2 <= c1) {
distance = BP.norm();
return B; // B is closest point
}
real b = c1 / c2;
T Pb, PPb;
Pb = A + b * AB;
PPb = P - Pb;
distance = PPb.norm();
return Pb; // closest point lies on AB
}
inline Vec3r closestPointOnPolygon(const Vec3r &point, const Polygon3r &poly)
{
// First cast a ray from the point onto the polygon plane
// If the ray intersects the polygon, then the intersection point
// is the closest point on the polygon
real t, u, v;
if (poly.rayIntersect(point, poly.getNormal(), t, u, v)) {
return point + poly.getNormal() * t;
}
// Otherwise, get the nearest point on each edge, and take the closest
real distance;
Vec3r closest = closestPointToSegment(
point, poly.getVertices()[2], poly.getVertices()[0], distance);
for (uint i = 0; i < 2; ++i) {
real t;
Vec3r p = closestPointToSegment(point, poly.getVertices()[i], poly.getVertices()[i + 1], t);
if (t < distance) {
distance = t;
closest = p;
}
}
return closest;
}
inline real distancePointToPolygon(const Vec3r &point, const Polygon3r &poly)
{
// First cast a ray from the point onto the polygon plane
// If the ray intersects the polygon, then the intersection point
// is the closest point on the polygon
real t, u, v;
if (poly.rayIntersect(point, poly.getNormal(), t, u, v)) {
return (t > 0.0) ? t : -t;
}
// Otherwise, get the nearest point on each edge, and take the closest
real distance = GeomUtils::distPointSegment(point, poly.getVertices()[2], poly.getVertices()[0]);
for (uint i = 0; i < 2; ++i) {
real t = GeomUtils::distPointSegment(point, poly.getVertices()[i], poly.getVertices()[i + 1]);
if (t < distance) {
distance = t;
}
}
return distance;
}
class Transform {
public:
virtual ~Transform() = 0;
virtual Vec3r operator()(const Vec3r &point) const = 0;
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:GridHelpers:Transform")
};
inline bool insideProscenium(const real proscenium[4], const Polygon3r &polygon)
{
// N.B. The bounding box check is redundant for inserting occluders into cells, because the cell
// selection code in insertOccluders has already guaranteed that the bounding boxes will overlap.
// First check the viewport edges, since they are the easiest case
// Check if the bounding box is entirely outside the proscenium
Vec3r bbMin, bbMax;
polygon.getBBox(bbMin, bbMax);
if (bbMax[0] < proscenium[0] || bbMin[0] > proscenium[1] || bbMax[1] < proscenium[2] ||
bbMin[1] > proscenium[3])
{
return false;
}
Vec3r boxCenter(proscenium[0] + (proscenium[1] - proscenium[0]) / 2.0,
proscenium[2] + (proscenium[3] - proscenium[2]) / 2.0,
0.0);
Vec3r boxHalfSize(
(proscenium[1] - proscenium[0]) / 2.0, (proscenium[3] - proscenium[2]) / 2.0, 1.0);
Vec3r triverts[3] = {
Vec3r(polygon.getVertices()[0][0], polygon.getVertices()[0][1], 0.0),
Vec3r(polygon.getVertices()[1][0], polygon.getVertices()[1][1], 0.0),
Vec3r(polygon.getVertices()[2][0], polygon.getVertices()[2][1], 0.0),
};
return GeomUtils::overlapTriangleBox(boxCenter, boxHalfSize, triverts);
}
inline vector<Vec3r> enumerateVertices(const vector<WOEdge *> &fedges)
{
vector<Vec3r> points;
// Iterate over vertices, storing projections in points
for (vector<WOEdge *>::const_iterator woe = fedges.begin(), woend = fedges.end(); woe != woend;
woe++)
{
points.push_back((*woe)->GetaVertex()->GetVertex());
}
return points;
}
void getDefaultViewProscenium(real viewProscenium[4]);
inline void expandProscenium(real proscenium[4], const Polygon3r &polygon)
{
Vec3r bbMin, bbMax;
polygon.getBBox(bbMin, bbMax);
const real epsilon = 1.0e-6;
if (bbMin[0] <= proscenium[0]) {
proscenium[0] = bbMin[0] - epsilon;
}
if (bbMin[1] <= proscenium[2]) {
proscenium[2] = bbMin[1] - epsilon;
}
if (bbMax[0] >= proscenium[1]) {
proscenium[1] = bbMax[0] + epsilon;
}
if (bbMax[1] >= proscenium[3]) {
proscenium[3] = bbMax[1] + epsilon;
}
}
inline void expandProscenium(real proscenium[4], const Vec3r &point)
{
const real epsilon = 1.0e-6;
if (point[0] <= proscenium[0]) {
proscenium[0] = point[0] - epsilon;
}
if (point[1] <= proscenium[2]) {
proscenium[2] = point[1] - epsilon;
}
if (point[0] >= proscenium[1]) {
proscenium[1] = point[0] + epsilon;
}
if (point[1] >= proscenium[3]) {
proscenium[3] = point[1] + epsilon;
}
}
}; // namespace GridHelpers
} /* namespace Freestyle */