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.
This commit is contained in:
Tamito Kajiyama 2014-05-22 22:37:35 +09:00
parent 7a86765095
commit 97d047a3e9
Notes: blender-bot 2023-04-04 07:45:26 +02:00
Referenced by issue #40320, Deformation Motion Blur makes objects render in wrong render layer?
Referenced by issue #40307, Crash with freestyle and particle hair
5 changed files with 32 additions and 5 deletions

View File

@ -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;
}

View File

@ -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")

View File

@ -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());

View File

@ -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)

View File

@ -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;