From b0d980371c99b5762f261b8ea5a8b71021c4171f Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 8 Apr 2008 23:50:50 +0000 Subject: [PATCH] fix stack recursion issues --- panda/src/egg/eggPrimitive.cxx | 39 +++++++++++++++++++++++++++++++++- panda/src/egg/eggPrimitive.h | 11 ++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/panda/src/egg/eggPrimitive.cxx b/panda/src/egg/eggPrimitive.cxx index dc792cf73d..20fa02728d 100644 --- a/panda/src/egg/eggPrimitive.cxx +++ b/panda/src/egg/eggPrimitive.cxx @@ -1172,6 +1172,42 @@ do_apply_flat_attribute(int vertex_index, EggAttributes *attrib) { void EggPrimitive:: set_connected_shading(EggPrimitive::Shading shading, const EggAttributes *neighbor) { + ConnectedShadingNodes connected_nodes; + + r_set_connected_shading(0, shading, neighbor, connected_nodes); + + // Pick up any additional nodes we couldn't visit because of the + // stack depth restrictions. + while (!connected_nodes.empty()) { + ConnectedShadingNodes next_nodes; + next_nodes.swap(connected_nodes); + + ConnectedShadingNodes::iterator ni; + for (ni = next_nodes.begin(); ni != next_nodes.end(); ++ni) { + r_set_connected_shading(0, (*ni)._shading, (*ni)._neighbor, connected_nodes); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: EggPrimitive::r_set_connected_shading +// Access: Private +// Description: Implements set_connected_shading, with some +// restrictions to prevent stack overflow. +//////////////////////////////////////////////////////////////////// +void EggPrimitive:: +r_set_connected_shading(int stack_depth, EggPrimitive::Shading shading, + const EggAttributes *neighbor, + ConnectedShadingNodes &next_nodes) { + if (stack_depth > 10000) { + // Too deep. Limit recursion. + ConnectedShadingNode next; + next._shading = shading; + next._neighbor = neighbor; + next_nodes.push_back(next); + return; + } + bool propagate = false; if (_connected_shading == S_unknown) { @@ -1218,7 +1254,8 @@ set_connected_shading(EggPrimitive::Shading shading, for (pi = vertex->pref_begin(); pi != vertex->pref_end(); ++pi) { - (*pi)->set_connected_shading(_connected_shading, this); + (*pi)->r_set_connected_shading(stack_depth + 1, _connected_shading, this, + next_nodes); } } } diff --git a/panda/src/egg/eggPrimitive.h b/panda/src/egg/eggPrimitive.h index 4842c6dcdf..60f7fdee85 100644 --- a/panda/src/egg/eggPrimitive.h +++ b/panda/src/egg/eggPrimitive.h @@ -212,6 +212,17 @@ protected: private: void set_connected_shading(Shading shading, const EggAttributes *neighbor); + class ConnectedShadingNode { + public: + Shading _shading; + const EggAttributes *_neighbor; + }; + typedef pvector ConnectedShadingNodes; + + void r_set_connected_shading(int depth_count, + Shading shading, const EggAttributes *neighbor, + ConnectedShadingNodes &connected_nodes); + private: typedef vector_PT_EggTexture Textures; Textures _textures;