www.pudn.com > tristripper-1.1.0-beta-5.zip > tri_stripper.h


 
////////////////////////////////////////////////////////////////////// 
// 
//  Copyright (C) 2004 Tanguy Fautré. 
// 
//  This software is provided 'as-is', without any express or implied 
//  warranty.  In no event will the authors be held liable for any damages 
//  arising from the use of this software. 
// 
//  Permission is granted to anyone to use this software for any purpose, 
//  including commercial applications, and to alter it and redistribute it 
//  freely, subject to the following restrictions: 
// 
//  1. The origin of this software must not be misrepresented; you must not 
//     claim that you wrote the original software. If you use this software 
//     in a product, an acknowledgment in the product documentation would be 
//     appreciated but is not required. 
//  2. Altered source versions must be plainly marked as such, and must not be 
//     misrepresented as being the original software. 
//  3. This notice may not be removed or altered from any source distribution. 
// 
//  Tanguy Fautré 
//  softdev@telenet.be 
// 
////////////////////////////////////////////////////////////////////// 
// 
//							Tri Stripper 
//							************ 
// 
// Post TnL cache aware triangle stripifier in O(n.log(n)). 
//           
// History: see ChangeLog 
// 
////////////////////////////////////////////////////////////////////// 
// SVN: $Id: tri_stripper.h 86 2005-06-08 17:47:27Z gpsnoopy $ 
////////////////////////////////////////////////////////////////////// 
 
// Protection against old C habits 
#if defined(max) 
#error "'max' macro defined! It's against the C++ standard. Please use 'std::max' instead (undefine 'max' macro if it was defined in another library)." 
#endif 
 
// Protection against old C habits 
#if defined(min) 
#error "'min' macro defined! It's against the C++ standard. Please use 'std::min' instead (undefine 'min' macro if it was defined in another library)." 
#endif 
 
 
 
#ifndef TRI_STRIPPER_HEADER_GUARD_TRI_STRIPPER_H 
#define TRI_STRIPPER_HEADER_GUARD_TRI_STRIPPER_H 
 
#include "public_types.h" 
 
#include "detail/cache_simulator.h" 
#include "detail/graph_array.h" 
#include "detail/heap_array.h" 
#include "detail/types.h" 
 
 
 
 
namespace triangle_stripper { 
 
 
 
 
class tri_stripper 
{ 
public: 
 
	tri_stripper(const indices & TriIndices); 
 
	void Strip(primitive_vector * out_pPrimitivesVector); 
 
	/* Stripifier Algorithm Settings */ 
	 
	// Set the post-T&L cache size (0 disables the cache optimizer). 
	void SetCacheSize(size_t CacheSize = 10); 
 
	// Set the minimum size of a triangle strip (should be at least 2 triangles). 
	// The stripifier discard any candidate strips that does not satisfy the minimum size condition. 
	void SetMinStripSize(size_t MinStripSize = 2); 
 
	// Set the backward search mode in addition to the forward search mode. 
	// In forward mode, the candidate strips are build with the current candidate triangle being the first 
	// triangle of the strip. When the backward mode is enabled, the stripifier also tests candidate strips 
	// where the current candidate triangle is the last triangle of the strip. 
	// Enable this if you want better results at the expense of being slightly slower. 
	// Note: Do *NOT* use this when the cache optimizer is enabled; it only gives worse results. 
	void SetBackwardSearch(bool Enabled = false); 
	 
	// Set the cache simulator FIFO behavior (does nothing if the cache optimizer is disabled). 
	// When enabled, the cache is simulated as a simple FIFO structure. However, when 
	// disabled, indices that trigger cache hits are not pushed into the FIFO structure. 
	// This allows simulating some GPUs that do not duplicate cache entries (e.g. NV25 or greater). 
	void SetPushCacheHits(bool Enabled = true); 
 
	/* End Settings */ 
 
private: 
 
	typedef detail::graph_array triangle_graph; 
	typedef detail::heap_array > triangle_heap; 
	typedef std::vector candidates; 
	typedef triangle_graph::node_iterator tri_iterator; 
	typedef triangle_graph::const_node_iterator const_tri_iterator; 
	typedef triangle_graph::out_arc_iterator link_iterator; 
	typedef triangle_graph::const_out_arc_iterator const_link_iterator; 
 
	void InitTriHeap(); 
	void Stripify(); 
	void AddLeftTriangles(); 
	void ResetStripIDs(); 
 
	detail::strip FindBestStrip(); 
	detail::strip ExtendToStrip(size_t Start, detail::triangle_order Order); 
	detail::strip BackExtendToStrip(size_t Start, detail::triangle_order Order, bool ClockWise); 
	const_link_iterator LinkToNeighbour(const_tri_iterator Node, bool ClockWise, detail::triangle_order & Order, bool NotSimulation); 
	const_link_iterator BackLinkToNeighbour(const_tri_iterator Node, bool ClockWise, detail::triangle_order & Order); 
	void BuildStrip(const detail::strip Strip); 
	void MarkTriAsTaken(size_t i); 
	void AddIndex(index i, bool NotSimulation); 
	void BackAddIndex(index i); 
	void AddTriangle(const detail::triangle & Tri, detail::triangle_order Order, bool NotSimulation); 
	void BackAddTriangle(const detail::triangle & Tri, detail::triangle_order Order); 
 
	bool Cache() const; 
	size_t CacheSize() const; 
 
	static detail::triangle_edge FirstEdge(const detail::triangle & Triangle, detail::triangle_order Order); 
	static detail::triangle_edge LastEdge(const detail::triangle & Triangle, detail::triangle_order Order); 
 
	primitive_vector			m_PrimitivesVector; 
	triangle_graph				m_Triangles; 
	triangle_heap				m_TriHeap; 
	candidates					m_Candidates; 
	detail::cache_simulator		m_Cache; 
	detail::cache_simulator		m_BackCache; 
	size_t						m_StripID; 
	size_t						m_MinStripSize; 
	bool						m_BackwardSearch; 
	bool						m_FirstRun; 
}; 
 
 
 
 
 
////////////////////////////////////////////////////////////////////////// 
// tri_stripper inline functions 
////////////////////////////////////////////////////////////////////////// 
 
inline void tri_stripper::SetCacheSize(const size_t CacheSize) 
{ 
	m_Cache.resize(CacheSize); 
	m_BackCache.resize(CacheSize); 
} 
 
 
inline void tri_stripper::SetMinStripSize(const size_t MinStripSize) 
{ 
	if (MinStripSize < 2) 
		m_MinStripSize = 2; 
	else 
		m_MinStripSize = MinStripSize; 
} 
 
 
inline void tri_stripper::SetBackwardSearch(const bool Enabled) 
{ 
	m_BackwardSearch = Enabled; 
} 
 
 
 
inline void tri_stripper::SetPushCacheHits(bool Enabled) 
{ 
	m_Cache.push_cache_hits(Enabled); 
} 
 
 
 
 
} // namespace triangle_stripper 
 
 
 
 
#endif // TRI_STRIPPER_HEADER_GUARD_TRI_STRIPPER_H