Fix T49479: Freestyle inconsistent line drawing with large geometry dimension.
Ray-plane intersection routine GeomUtils::intersectRayPlane() was used with an unnormalized direction vector as input.
This commit is contained in:
parent
6559ab2d51
commit
7f262acb92
Notes:
blender-bot
2023-02-14 07:33:55 +01:00
Referenced by issue #49479, Freestyle inconsistent line drawing with large geometry dimension
|
@ -470,6 +470,8 @@ bool intersectRayTriangle(const Vec3r& orig, const Vec3r& dir, const Vec3r& v0,
|
|||
}
|
||||
|
||||
// Intersection between plane and ray, adapted from Graphics Gems, Didier Badouel
|
||||
// The plane is represented by a set of points P implicitly defined as dot(norm, P) + d = 0.
|
||||
// The ray is represented as r(t) = orig + dir * t.
|
||||
intersection_test intersectRayPlane(const Vec3r& orig, const Vec3r& dir, const Vec3r& norm, const real d,
|
||||
real& t, const real epsilon)
|
||||
{
|
||||
|
|
|
@ -57,7 +57,7 @@ using namespace std;
|
|||
|
||||
template <typename G, typename I>
|
||||
static void findOccludee(FEdge *fe, G& /*grid*/, I& occluders, real epsilon, WFace **oaWFace,
|
||||
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices)
|
||||
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector<WVertex*>& faceVertices)
|
||||
{
|
||||
WFace *face = NULL;
|
||||
if (fe->isSmooth()) {
|
||||
|
@ -125,7 +125,7 @@ static void findOccludee(FEdge *fe, G& /*grid*/, I& occluders, real epsilon, WFa
|
|||
// check whether the edge and the polygon plane are coincident:
|
||||
//-------------------------------------------------------------
|
||||
//first let us compute the plane equation.
|
||||
if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, p->getNormal(), d, t, epsilon))
|
||||
if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, p->getNormal(), d, t, epsilon))
|
||||
{
|
||||
#if LOGGING
|
||||
if (_global.debug & G_DEBUG_FREESTYLE) {
|
||||
|
@ -172,10 +172,11 @@ template <typename G, typename I>
|
|||
static void findOccludee(FEdge *fe, G& grid, real epsilon, ViewEdge * /*ve*/, WFace **oaFace)
|
||||
{
|
||||
Vec3r A;
|
||||
Vec3r edge;
|
||||
Vec3r edgeDir;
|
||||
Vec3r origin;
|
||||
A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
|
||||
edge = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
|
||||
edgeDir = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
|
||||
edgeDir.normalize();
|
||||
origin = Vec3r((fe)->vertexA()->point3D());
|
||||
Vec3r u;
|
||||
if (grid.orthographicProjection()) {
|
||||
|
@ -199,7 +200,7 @@ static void findOccludee(FEdge *fe, G& grid, real epsilon, ViewEdge * /*ve*/, WF
|
|||
}
|
||||
|
||||
I occluders(grid, A, epsilon);
|
||||
findOccludee<G, I>(fe, grid, occluders, epsilon, oaFace, u, A, origin, edge, faceVertices);
|
||||
findOccludee<G, I>(fe, grid, occluders, epsilon, oaFace, u, A, origin, edgeDir, faceVertices);
|
||||
}
|
||||
|
||||
// computeVisibility takes a pointer to foundOccluders, instead of using a reference,
|
||||
|
@ -211,11 +212,12 @@ static int computeVisibility(ViewMap *viewMap, FEdge *fe, G& grid, real epsilon,
|
|||
int qi = 0;
|
||||
|
||||
Vec3r center;
|
||||
Vec3r edge;
|
||||
Vec3r edgeDir;
|
||||
Vec3r origin;
|
||||
|
||||
center = fe->center3d();
|
||||
edge = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
|
||||
edgeDir = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
|
||||
edgeDir.normalize();
|
||||
origin = Vec3r(fe->vertexA()->point3D());
|
||||
|
||||
Vec3r vp;
|
||||
|
@ -337,7 +339,7 @@ static int computeVisibility(ViewMap *viewMap, FEdge *fe, G& grid, real epsilon,
|
|||
// check whether the edge and the polygon plane are coincident:
|
||||
//-------------------------------------------------------------
|
||||
//first let us compute the plane equation.
|
||||
if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, p->getNormal(), d, t, epsilon)) {
|
||||
if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, p->getNormal(), d, t, epsilon)) {
|
||||
#if LOGGING
|
||||
if (_global.debug & G_DEBUG_FREESTYLE) {
|
||||
cout << "\t\tRejecting occluder for target coincidence." << endl;
|
||||
|
@ -391,7 +393,7 @@ static int computeVisibility(ViewMap *viewMap, FEdge *fe, G& grid, real epsilon,
|
|||
}
|
||||
|
||||
// Find occludee
|
||||
findOccludee<G, I>(fe, grid, occluders, epsilon, oaWFace, u, center, origin, edge, faceVertices);
|
||||
findOccludee<G, I>(fe, grid, occluders, epsilon, oaWFace, u, center, origin, edgeDir, faceVertices);
|
||||
|
||||
return qi;
|
||||
}
|
||||
|
@ -1788,7 +1790,7 @@ void ViewMapBuilder::ComputeVeryFastRayCastingVisibility(ViewMap *ioViewMap, rea
|
|||
}
|
||||
|
||||
void ViewMapBuilder::FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
|
||||
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices)
|
||||
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector<WVertex*>& faceVertices)
|
||||
{
|
||||
WFace *face = NULL;
|
||||
if (fe->isSmooth()) {
|
||||
|
@ -1856,7 +1858,7 @@ void ViewMapBuilder::FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3
|
|||
continue;
|
||||
}
|
||||
else {
|
||||
if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, normal, d, t, epsilon))
|
||||
if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, normal, d, t, epsilon))
|
||||
continue;
|
||||
}
|
||||
if ((*p)->rayIntersect(A, v, t, t_u, t_v)) {
|
||||
|
@ -1883,10 +1885,11 @@ void ViewMapBuilder::FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3
|
|||
OccludersSet occluders;
|
||||
|
||||
Vec3r A;
|
||||
Vec3r edge;
|
||||
Vec3r edgeDir;
|
||||
Vec3r origin;
|
||||
A = Vec3r(((fe)->vertexA()->point3D() + (fe)->vertexB()->point3D()) / 2.0);
|
||||
edge = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
|
||||
edgeDir = Vec3r((fe)->vertexB()->point3D() - (fe)->vertexA()->point3D());
|
||||
edgeDir.normalize();
|
||||
origin = Vec3r((fe)->vertexA()->point3D());
|
||||
Vec3r u;
|
||||
if (_orthographicProjection) {
|
||||
|
@ -1910,7 +1913,7 @@ void ViewMapBuilder::FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3
|
|||
if (face)
|
||||
face->RetrieveVertexList(faceVertices);
|
||||
|
||||
return FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, A, origin, edge, faceVertices);
|
||||
return FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, A, origin, edgeDir, faceVertices);
|
||||
}
|
||||
|
||||
int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real epsilon, set<ViewShape*>& oOccluders,
|
||||
|
@ -1920,11 +1923,12 @@ int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real eps
|
|||
int qi = 0;
|
||||
|
||||
Vec3r center;
|
||||
Vec3r edge;
|
||||
Vec3r edgeDir;
|
||||
Vec3r origin;
|
||||
|
||||
center = fe->center3d();
|
||||
edge = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
|
||||
edgeDir = Vec3r(fe->vertexB()->point3D() - fe->vertexA()->point3D());
|
||||
edgeDir.normalize();
|
||||
origin = Vec3r(fe->vertexA()->point3D());
|
||||
// Is the edge outside the view frustum ?
|
||||
Vec3r gridOrigin(iGrid->getOrigin());
|
||||
|
@ -2062,7 +2066,7 @@ int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real eps
|
|||
//-------------------------------------------------------------
|
||||
//first let us compute the plane equation.
|
||||
|
||||
if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edge, normal, d, t, epsilon)) {
|
||||
if (GeomUtils::COINCIDENT == GeomUtils::intersectRayPlane(origin, edgeDir, normal, d, t, epsilon)) {
|
||||
#if LOGGING
|
||||
if (_global.debug & G_DEBUG_FREESTYLE) {
|
||||
cout << "\t\tRejecting occluder for target coincidence." << endl;
|
||||
|
@ -2099,7 +2103,7 @@ int ViewMapBuilder::ComputeRayCastingVisibility(FEdge *fe, Grid *iGrid, real eps
|
|||
}
|
||||
|
||||
// Find occludee
|
||||
FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, center, origin, edge, faceVertices);
|
||||
FindOccludee(fe, iGrid, epsilon, oaPolygon, timestamp, u, center, origin, edgeDir, faceVertices);
|
||||
|
||||
return qi;
|
||||
}
|
||||
|
|
|
@ -250,7 +250,7 @@ protected:
|
|||
// FIXME
|
||||
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp);
|
||||
void FindOccludee(FEdge *fe, Grid *iGrid, real epsilon, Polygon3r **oaPolygon, unsigned timestamp,
|
||||
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector<WVertex*>& faceVertices);
|
||||
Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector<WVertex*>& faceVertices);
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapBuilder")
|
||||
|
|
Loading…
Reference in New Issue