From 7f262acb92e5873f3c6fd63520bcec60f8e220dc Mon Sep 17 00:00:00 2001 From: Tamito Kajiyama Date: Wed, 28 Dec 2016 18:05:28 +0900 Subject: 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. --- .../freestyle/intern/view_map/ViewMapBuilder.cpp | 40 ++++++++++++---------- .../freestyle/intern/view_map/ViewMapBuilder.h | 2 +- 2 files changed, 23 insertions(+), 19 deletions(-) (limited to 'source/blender/freestyle/intern/view_map') diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp index 380bb0dd3ca..794c782bb73 100644 --- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp +++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp @@ -57,7 +57,7 @@ using namespace std; template static void findOccludee(FEdge *fe, G& /*grid*/, I& occluders, real epsilon, WFace **oaWFace, - Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edge, vector& faceVertices) + Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector& 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 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(fe, grid, occluders, epsilon, oaFace, u, A, origin, edge, faceVertices); + findOccludee(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(fe, grid, occluders, epsilon, oaWFace, u, center, origin, edge, faceVertices); + findOccludee(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& faceVertices) + Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector& 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& 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; } diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h index 36497bf8d22..440ae93c7df 100644 --- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.h +++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.h @@ -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& faceVertices); + Vec3r& u, Vec3r& A, Vec3r& origin, Vec3r& edgeDir, vector& faceVertices); #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMapBuilder") -- cgit v1.2.3