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