diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2014-05-22 17:37:35 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2014-05-22 18:18:47 +0400 |
commit | 97d047a3e9a52d9e2d8c0eee6932ab9ab9199ab9 (patch) | |
tree | 5eb2a0155474121a60387cdb02c1434a1cfbd2a5 /source | |
parent | 7a8676509505bf5fbf50943f3bcc561bf95fabef (diff) |
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.
Diffstat (limited to 'source')
5 files changed, 32 insertions, 5 deletions
diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp index 2bd31ea03a1..176199600ac 100644 --- a/source/blender/freestyle/intern/application/Controller.cpp +++ b/source/blender/freestyle/intern/application/Controller.cpp @@ -298,12 +298,19 @@ int Controller::LoadMesh(Render *re, SceneRenderLayer *srl) _bboxDiag = (_RootNode->bbox().getMax() - _RootNode->bbox().getMin()).norm(); if (G.debug & G_DEBUG_FREESTYLE) { - cout << "Triangles nb : " << _SceneNumFaces << endl; + cout << "Triangles nb : " << _SceneNumFaces << " imported, " << + _winged_edge->getNumFaces() << " retained" << endl; cout << "Bounding Box : " << _bboxDiag << endl; } ClearRootNode(); + _SceneNumFaces = _winged_edge->getNumFaces(); + if (_SceneNumFaces == 0) { + DeleteWingedEdge(); + return 1; + } + return 0; } 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<WShape *>::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<WShape *>& getWShapes() @@ -1321,8 +1323,14 @@ public: return _wshapes; } + unsigned getNumFaces() + { + return _numFaces; + } + private: vector<WShape *> _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; |