From 97d047a3e9a52d9e2d8c0eee6932ab9ab9199ab9 Mon Sep 17 00:00:00 2001 From: Tamito Kajiyama Date: Thu, 22 May 2014 22:37:35 +0900 Subject: Fix T40307: Crash with freestyle and particle hair. The scene file provided by the problem report has many degenerate faces coming from a particle system. These zero-area faces were not expected in the ray-casting line visibility algorithms of Freestyle. Now degenerate faces are properly excluded from the imported mesh data and not fed to the line visibility algorithms. --- source/blender/freestyle/intern/winged_edge/WEdge.h | 8 ++++++++ .../blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp | 5 ++++- .../freestyle/intern/winged_edge/WingedEdgeBuilder.cpp | 13 +++++++++++-- .../freestyle/intern/winged_edge/WingedEdgeBuilder.h | 2 +- 4 files changed, 24 insertions(+), 4 deletions(-) (limited to 'source/blender/freestyle/intern/winged_edge') diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.h b/source/blender/freestyle/intern/winged_edge/WEdge.h index 5dda41ad279..54461a6e8a6 100644 --- a/source/blender/freestyle/intern/winged_edge/WEdge.h +++ b/source/blender/freestyle/intern/winged_edge/WEdge.h @@ -1309,11 +1309,13 @@ public: for (vector::iterator it = _wshapes.begin(); it != _wshapes.end(); it++) delete *it; _wshapes.clear(); + _numFaces = 0; } void addWShape(WShape *wshape) { _wshapes.push_back(wshape); + _numFaces += wshape->GetFaceList().size(); } vector& getWShapes() @@ -1321,8 +1323,14 @@ public: return _wshapes; } + unsigned getNumFaces() + { + return _numFaces; + } + private: vector _wshapes; + unsigned _numFaces; #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:WingedEdge") diff --git a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp index eab638840e5..590e03255f5 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp +++ b/source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp @@ -36,7 +36,10 @@ void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) if (_pRenderMonitor && _pRenderMonitor->testBreak()) return; WXShape *shape = new WXShape; - buildWShape(*shape, ifs); + if (!buildWShape(*shape, ifs)) { + delete shape; + return; + } shape->setId(ifs.getId().getFirst()); shape->setName(ifs.getName()); //ifs.setId(shape->GetId()); diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp index c83abe85318..c9f2f3badab 100644 --- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp +++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp @@ -43,7 +43,10 @@ void WingedEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) if (_pRenderMonitor && _pRenderMonitor->testBreak()) return; WShape *shape = new WShape; - buildWShape(*shape, ifs); + if (!buildWShape(*shape, ifs)) { + delete shape; + return; + } shape->setId(ifs.getId().getFirst()); //ifs.setId(shape->GetId()); } @@ -80,7 +83,7 @@ void WingedEdgeBuilder::visitNodeTransformAfter(NodeTransform&) _matrices_stack.pop_back(); } -void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) +bool WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) { unsigned int vsize = ifs.vsize(); unsigned int nsize = ifs.nsize(); @@ -171,6 +174,9 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) delete[] new_vertices; delete[] new_normals; + if (shape.GetFaceList().size() == 0) // this may happen due to degenerate triangles + return false; + // compute bbox shape.ComputeBBox(); // compute mean edge size: @@ -198,8 +204,11 @@ void WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) (*wv)->setSmooth(false); } } + // Adds the new WShape to the WingedEdge structure _winged_edge->addWShape(&shape); + + return true; } void WingedEdgeBuilder::buildWVertices(WShape& shape, const real *vertices, unsigned vsize) diff --git a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h index 7fd5cd8443a..36f090f4ae9 100644 --- a/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h +++ b/source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h @@ -117,7 +117,7 @@ public: } protected: - virtual void buildWShape(WShape& shape, IndexedFaceSet& ifs); + virtual bool buildWShape(WShape& shape, IndexedFaceSet& ifs); virtual void buildWVertices(WShape& shape, const real *vertices, unsigned vsize); RenderMonitor *_pRenderMonitor; -- cgit v1.2.3