[Bf-blender-cvs] [97d047a] master: Fix T40307: Crash with freestyle and particle hair.

Tamito Kajiyama noreply at git.blender.org
Thu May 22 16:19:31 CEST 2014


Commit: 97d047a3e9a52d9e2d8c0eee6932ab9ab9199ab9
Author: Tamito Kajiyama
Date:   Thu May 22 22:37:35 2014 +0900
https://developer.blender.org/rB97d047a3e9a52d9e2d8c0eee6932ab9ab9199ab9

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.

===================================================================

M	source/blender/freestyle/intern/application/Controller.cpp
M	source/blender/freestyle/intern/winged_edge/WEdge.h
M	source/blender/freestyle/intern/winged_edge/WXEdgeBuilder.cpp
M	source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.cpp
M	source/blender/freestyle/intern/winged_edge/WingedEdgeBuilder.h

===================================================================

diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index 2bd31ea..1761996 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 5dda41a..54461a6 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 eab6388..590e032 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 c83abe8..c9f2f3b 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 7fd5cd8..36f090f 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;




More information about the Bf-blender-cvs mailing list