<commit_before>/*
    Copyright (C) 1997, 1998, 1999 by <NAME>
	(Digital Dawn Graphics Inc)
  
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
  
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.
  
    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _ddgMesh_Class_
#define _ddgMesh_Class_

#include "csterr/ddghemap.h"
#include "csterr/ddgbbox.h"
#include "csterr/ddgsplay.h"
#include "csterr/ddgvec.h"

class ddgTBinTree;
class ddgTBinMesh;

// Block size of bintrees within a binmesh.
#define ddgTBinMesh_size 64

typedef unsigned int ddgTriIndex;
typedef unsigned int ddgTreeIndex;
typedef enum { eINNER = 0, eTOP = 1, eLEFT = 2, eDIAG = 3} Edge;
/**
 * The information in this class is the same for each TBinTree and can
 * be computed once (and stored) and can be shared amoung all TBinTrees.
 */
class WEXP ddgMSTri
{
public:
	/// Our position on the height grid.
	unsigned int row, col; // Maybe possible to calculate.
	/**
	 *  The indices of the 2 other vertices which are a part of this triangle.
	 *  The 3rd vertex is our own index in the mesh.
	 */
	ddgTriIndex v0, v1;
	/**
	 * Index of the merge diamond which is our neighbour.
	 * If we are on an edge, this may be in another TBinTree, and the
	 * neighbour field will indicate which one.
	 */
	ddgTriIndex neighbour;
	/**
	 * If this is not zero, the neighbour is in another TBinTree.
	 * the flag indicates which neighbour tree the edge is in.
	 * 0 - inner, 1 - top, 2 - left, 3 - diag.
	 */
	Edge edge(void)
	{
		if (row == 0)
			return eTOP;
		if (col == 0)
			return eLEFT;
		if (row + col == ddgTBinMesh_size)
			return eDIAG;
		return eINNER;
	}
};


/**
 *  Vertex cache.
 * all vertices which are transformed to camera space
 * are kept by this cache in case they are needed again for
 * another calculation during this frame.
 * Note entry 0 in the cache is unused.
 */
class WEXP ddgVCache {
	/// Max size of cache.
	unsigned short	_size;
	/// Current size.
	unsigned short _used;
	/// Pointer to array of Vector3s.
	csVector3		*_cache;
public:
	/// Create cache.
	ddgVCache();
	/// Destroy cache.
	~ddgVCache();
	/// Initialize the cache.
	void init (unsigned int size );
	/// Get entry.
	inline csVector3		*get(unsigned short index)
	{
		return &(_cache[index]);
	}
	/// New entry.
	inline unsigned short	alloc(void)
	{
		ddgAssert(_used + 1 < _size);
		_used++;
		return _used;
	}
	/// Reset cache to empty.
	inline void reset(void)
	{
		_used = 0;
	}
};

/**
 * ROAM Triangle Bintree mesh shared data.<br>
 *
 * General construction of a BinTree and the indexing of vertices:<br>
 *
 * The top level triangle consists of vertices (0,3,2), triangle
 * vertices are enumerated counter clock-wise.
 * Va is the top of the triangle, Vc is the new split point or center,
 * V0 is the left coord w.r.t. vc and V1 is the right coord w.r.t. vc.
 * This triangle has 2 children (the Bin in BinTree) which are T0 and T1,
 * (0,1,n+1) and (0,n,1), respectively (the left and the right child with
 * respect to vc).<br>
 * Each sub triangle can be split again, 1st the left into (1,2,0) and
 * (1,n+1,2) and the right into (1,0,3) and (1,3,n).  For the left and right
 * sub triangle, 1 becomes va and 2 becomes vc for the left child and
 * 3 becomes vc for the right child, etc.
 * A triangle is identified by its Vc coordinate since that is unique, Va,
 * V0 and V1 are shared with other triangles.  Therefor all information
 * that it stores is associated with Vc.
 * Each sub level in the tree adds twice as many triangles as were present
 * in the previous level.  So with each level required storage double
 * That only leaves a problem for the top most triangle which needs to
 * store its left and right children from somwhere.  In this implementation,
 * this info is stored at index n and n+1.
 * This scheme allows very fast computation of the indices which represent
 * the parent or children of any given triangle.
 *<pre>
 * This diagram shows the index numbers, names for the top level triangle
 * (va,vc,v0,v1) and to map coordinates of the top level vertices.
 *
 *        0,0      3     size,0
 *    (va) 0 +-----+-----+ n (v1)
 *           |\    |    /
 *           | \   T1  /
 *           |  \  |  /
 *           |   \ | /
 *           |    \|/
 *         2 +-T0--+ 1 (vc)
 *           |    /  
 *           |   /
 *           |  /
 *           | /
 *           |/
 *   0,size  + n+1 (v0)
 *</pre>
 * Neighbours and Merge Diamonds:<br>
 * If the triangles 2 and 3 are split again, their vc vertices will lie
 * halfway between vertices 0 and 1.  They will produce 4 children which
 * all share this common vc, however since the triangles (2 and 3) are
 * seperate triangles, the vc point is stored twice, once for 2 and once for 3.
 * To keep the mesh from cracking, if 2 is split, 3 must split also. No
 * T-junctions are allowed.  Because of this rule, 2 and 3 are considered
 * neighbours and they form a merge diamond.
 * There is no easy way to know which triangle is the neighbour of another,
 * for this reason neigbour indices are precomputed and stored in a table.
 * All other indices are readily available from the given triangle's own index.
 *<p><h4>
 * The mesh update process:
 *</h4>
 *<pre>
 * Draw
 *   Calculate
 *       if Camera has moved or terrain has changed.
 *          {
 *          Update CameraMatrix for culling.
 *          Reset Visibility data for all triangles up to the point that they
 *             are in split queue.
 *          recalculate Visiblity of each visible triangle recursively
 *             sets update flag.
 *             calculates vertices in camera coords and caches them for later use.
 *          merge all diamonds which are not visible.
 *          UpdatePriorities
 *             for all visible triangles,
 *                compute their priority, sets uptodatep flag.    
 *             resort the split and merge queue accordingly.
 *          BalanceQueue
 *             split and merge triangles until
 *                the right number of triangles is available and
 *                the maximum split priority is greater than the minimum merge priority
 *          }
 *   Render
 *      for all visible triangles in the Split queue.
 *         build vertex array.
 *         render the vertex array.
 *</pre>
 */


class WEXP ddgTBinMesh
{
	/// Levels in the mesh (log(size)/log(2));
	unsigned int _maxLevel;
	/// The number of triangles in the TBinTree.
	unsigned int _triNo;
	/// Dirty state.
	bool		_dirty;
	/// Max number of bintrees to manage.
	unsigned int _bintreeMax;
	/// Bintree's managed by this mesh
	ddgTBinTree ** _bintree;
	/// A transformed vertex cache.
	ddgVCache		_vcache;
	/// Number of visible triangles in the mesh.
	unsigned int _visTri;
	/// Split queue.
	ddgSplayTree	*_qs;
	/// Merge queue.
	ddgSplayTree	*_qm;
	/// Split queue iterator
	ddgSplayIterator		*_qsi;
	/// Merge queue
	ddgSplayIterator		*_qmi;
	/// Number of rows of bintrees.
	unsigned int	_nr;
	/// Number of columns of bintrees.
	unsigned int	_nc;
    /// World to camera space transformation matrix must be initialized before calling calculate.
    double          *_wtoc;
    /// The bounding box in screen space.
    ddgBBox         *_camBBox;
    /// The field of view.
    float           _tanHalfFOV;
	/// The min number of triangles that should be displayed.
	unsigned int	_mindetail;
	/// The max number of triangles that should be displayed.
	unsigned int	_maxdetail;
	/// Distant clip range triangles beyond this point are not needed.
	float		_farclip;
	/// Near clip range triangles beyond this point are not needed.
	float		_nearclip;
	/// Triangles beyond this point have their priority recalculated once every n frames.
	float		_progDist;
	/// Merge queue active.
	bool		_merge;
	/// Total number of triangles rendered.  For statistics.
	unsigned int _triCount;
	/// Total number of priorities calculated.
	unsigned int _priCount;
	/// Total number of queue insertions.
	unsigned int _insCount;
	/// Total number of queue removals.
	unsigned int _remCount;
	/// Total number of queue updates.
	unsigned int _movCount;
	/// Number of balanceOperations this frame.
	unsigned int _balanceCount;
public:
	/**
     * Constructor, pass in the size of the BinTree.
	 *  s = size along one edge of one BinTree.
	 *  i = image object from which to contruct the mesh.
     */
	ddgTBinMesh( ddgHeightMap *i);
	/// Destroy the Bintree mesh.
	~ddgTBinMesh(void);
	/**
	 * Pointer to an array of MTri objects.
	 */
	ddgMSTri* stri;
	/// Initialize the mesh.
	bool init( double *worldToCameraMatrix, ddgBBox *camClipBox, float fov );
	/**
	 * Initialize the neighbour field of all triangles.
	 */
	void initNeighbours( void );
	/**
	 *  Initialize the vertex and row/col data of the STri. 
	 *  Passed in are the triangles which carry the points
	 *  that describe the current triangle.
	 *  va is immediate parent.
	 *  v1 and v0 are the sub triangles of va. 
	 */
	void initVertex( unsigned int level,
			   ddgTriIndex va,
			   ddgTriIndex v1,
			   ddgTriIndex v0,
			   ddgTriIndex vc);
    /// Return the edge status of a tri.
    unsigned int edge(ddgTriIndex i)
    {
        return stri[i].edge();
    }

	/// Return the required LOD.
	unsigned int mindetail( void ) { return _mindetail; }
	/// Set the required LOD.
	void mindetail( unsigned int d ) { _mindetail = d; }
	/// Return the required LOD.
	unsigned int maxdetail( void ) { return _maxdetail; }
	/// Set the required LOD.
	void maxdetail( unsigned int d ) { _maxdetail = d; }

	/// Return the split queue 
	ddgSplayTree *qs(void) { return _qs; }
	/// Return the merge queue 
	ddgSplayTree *qm(void) { return _qm; }
	/// Return an iterator for the visible set of triangles.
	ddgSplayIterator* qsi(void) { return _qsi; }
	/// Return a priority from the merge queue.
	unsigned int prioritySQ( ddgSplayIterator *i );
	/// Return the tree of an item from the split queue.
	ddgTBinTree* treeSQ( ddgSplayIterator *i )
	{
		return getBinTree(_qs->retrieve(i->current())->tree());
	}
	/// Return an item from the split queue.
	unsigned int indexSQ(ddgSplayIterator *i)
	{
		return  _qs->retrieve(i->current())->index();
	}
	/// Return a priority from the merge queue.
	unsigned int priorityMQ( ddgSplayIterator *i );
	/// Return the tree of an item from the merge queue.
	ddgTBinTree* treeMQ( ddgSplayIterator *i )
	{
		return getBinTree(_qm->retrieve(i->current())->tree());
	}
	/// Return an item from the split queue.
	unsigned int indexMQ(ddgSplayIterator *i)
	{
		return _qm->retrieve(i->current())->index();
	}
	/// Return the number of triangles.
	unsigned int triNo(void) { return _triNo; }
	/**
	 *  Split the best split candidate.
	 */
	bool splitQueue(void);
	/**
	 *  Merge the best merge candidate.
	 */
	bool mergeQueue(void);
	/**
	 *  Balance the split and merge queues.
	 * Returns the number of iterations it took to get to a balanced state.
	 */
	unsigned int balanceQueue(void);
	/// Empty the split queue.
	void clearSQ(void);
	/// Empty the merge queue.
	void clearMQ(void);

	/// Return the number of visible triangles in the mesh.
	unsigned int visTri(void) { return _visTri; }

	/// Recalculate the number of visibile triangles.
	unsigned int updateVisibleTri(void);

	/// Return the number of split levels.
	unsigned int maxLevel( void ) { return _maxLevel; }

	/// Set dirty state.
	void dirty( bool d ) { _dirty = d; }
	/// Get dirty state.
	bool dirty( void ) { return _dirty; }

	/**
	 * Calculate the optimal set of triangles for the mesh at current camera pos.
	 * returns true if any calculation was performed.
	 */
	bool calculate(void);

	/// Function to add a bintree.
	void addBinTree( ddgTBinTree *bt );
	/// Function to remove a bintree.
	void removeBinTree( ddgTBinTree *bt );
	/// Return the bintree for a given index.
	ddgTBinTree *getBinTree( ddgTreeIndex i)
	{ ddgAssert(i < _bintreeMax && i >= 0); return _bintree[i]; }<commit_msg>Worked around OpenStep compiler bug where it generates unlinkable code if an inline method calls a second inline method before the compiler has seen the definition of the second method.  A simple textual reorganization of the code solved the problem.<commit_after>/*
    Copyright (C) 1997, 1998, 1999 by <NAME>
	(Digital Dawn Graphics Inc)
  
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
  
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.
  
    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _ddgMesh_Class_
#define _ddgMesh_Class_

#include "csterr/ddghemap.h"
#include "csterr/ddgbbox.h"
#include "csterr/ddgsplay.h"
#include "csterr/ddgvec.h"

class ddgTBinTree;
class ddgTBinMesh;

// Block size of bintrees within a binmesh.
#define ddgTBinMesh_size 64

typedef unsigned int ddgTriIndex;
typedef unsigned int ddgTreeIndex;
typedef enum { eINNER = 0, eTOP = 1, eLEFT = 2, eDIAG = 3} Edge;
/**
 * The information in this class is the same for each TBinTree and can
 * be computed once (and stored) and can be shared amoung all TBinTrees.
 */
class WEXP ddgMSTri
{
public:
	/// Our position on the height grid.
	unsigned int row, col; // Maybe possible to calculate.
	/**
	 *  The indices of the 2 other vertices which are a part of this triangle.
	 *  The 3rd vertex is our own index in the mesh.
	 */
	ddgTriIndex v0, v1;
	/**
	 * Index of the merge diamond which is our neighbour.
	 * If we are on an edge, this may be in another TBinTree, and the
	 * neighbour field will indicate which one.
	 */
	ddgTriIndex neighbour;
	/**
	 * If this is not zero, the neighbour is in another TBinTree.
	 * the flag indicates which neighbour tree the edge is in.
	 * 0 - inner, 1 - top, 2 - left, 3 - diag.
	 */
	Edge edge(void)
	{
		if (row == 0)
			return eTOP;
		if (col == 0)
			return eLEFT;
		if (row + col == ddgTBinMesh_size)
			return eDIAG;
		return eINNER;
	}
};


/**
 *  Vertex cache.
 * all vertices which are transformed to camera space
 * are kept by this cache in case they are needed again for
 * another calculation during this frame.
 * Note entry 0 in the cache is unused.
 */
class WEXP ddgVCache {
	/// Max size of cache.
	unsigned short	_size;
	/// Current size.
	unsigned short _used;
	/// Pointer to array of Vector3s.
	csVector3		*_cache;
public:
	/// Create cache.
	ddgVCache();
	/// Destroy cache.
	~ddgVCache();
	/// Initialize the cache.
	void init (unsigned int size );
	/// Get entry.
	inline csVector3		*get(unsigned short index)
	{
		return &(_cache[index]);
	}
	/// New entry.
	inline unsigned short	alloc(void)
	{
		ddgAssert(_used + 1 < _size);
		_used++;
		return _used;
	}
	/// Reset cache to empty.
	inline void reset(void)
	{
		_used = 0;
	}
};

/**
 * ROAM Triangle Bintree mesh shared data.<br>
 *
 * General construction of a BinTree and the indexing of vertices:<br>
 *
 * The top level triangle consists of vertices (0,3,2), triangle
 * vertices are enumerated counter clock-wise.
 * Va is the top of the triangle, Vc is the new split point or center,
 * V0 is the left coord w.r.t. vc and V1 is the right coord w.r.t. vc.
 * This triangle has 2 children (the Bin in BinTree) which are T0 and T1,
 * (0,1,n+1) and (0,n,1), respectively (the left and the right child with
 * respect to vc).<br>
 * Each sub triangle can be split again, 1st the left into (1,2,0) and
 * (1,n+1,2) and the right into (1,0,3) and (1,3,n).  For the left and right
 * sub triangle, 1 becomes va and 2 becomes vc for the left child and
 * 3 becomes vc for the right child, etc.
 * A triangle is identified by its Vc coordinate since that is unique, Va,
 * V0 and V1 are shared with other triangles.  Therefor all information
 * that it stores is associated with Vc.
 * Each sub level in the tree adds twice as many triangles as were present
 * in the previous level.  So with each level required storage double
 * That only leaves a problem for the top most triangle which needs to
 * store its left and right children from somwhere.  In this implementation,
 * this info is stored at index n and n+1.
 * This scheme allows very fast computation of the indices which represent
 * the parent or children of any given triangle.
 *<pre>
 * This diagram shows the index numbers, names for the top level triangle
 * (va,vc,v0,v1) and to map coordinates of the top level vertices.
 *
 *        0,0      3     size,0
 *    (va) 0 +-----+-----+ n (v1)
 *           |\    |    /
 *           | \   T1  /
 *           |  \  |  /
 *           |   \ | /
 *           |    \|/
 *         2 +-T0--+ 1 (vc)
 *           |    /  
 *           |   /
 *           |  /
 *           | /
 *           |/
 *   0,size  + n+1 (v0)
 *</pre>
 * Neighbours and Merge Diamonds:<br>
 * If the triangles 2 and 3 are split again, their vc vertices will lie
 * halfway between vertices 0 and 1.  They will produce 4 children which
 * all share this common vc, however since the triangles (2 and 3) are
 * seperate triangles, the vc point is stored twice, once for 2 and once for 3.
 * To keep the mesh from cracking, if 2 is split, 3 must split also. No
 * T-junctions are allowed.  Because of this rule, 2 and 3 are considered
 * neighbours and they form a merge diamond.
 * There is no easy way to know which triangle is the neighbour of another,
 * for this reason neigbour indices are precomputed and stored in a table.
 * All other indices are readily available from the given triangle's own index.
 *<p><h4>
 * The mesh update process:
 *</h4>
 *<pre>
 * Draw
 *   Calculate
 *       if Camera has moved or terrain has changed.
 *          {
 *          Update CameraMatrix for culling.
 *          Reset Visibility data for all triangles up to the point that they
 *             are in split queue.
 *          recalculate Visiblity of each visible triangle recursively
 *             sets update flag.
 *             calculates vertices in camera coords and caches them for later use.
 *          merge all diamonds which are not visible.
 *          UpdatePriorities
 *             for all visible triangles,
 *                compute their priority, sets uptodatep flag.    
 *             resort the split and merge queue accordingly.
 *          BalanceQueue
 *             split and merge triangles until
 *                the right number of triangles is available and
 *                the maximum split priority is greater than the minimum merge priority
 *          }
 *   Render
 *      for all visible triangles in the Split queue.
 *         build vertex array.
 *         render the vertex array.
 *</pre>
 */


class WEXP ddgTBinMesh
{
	/// Levels in the mesh (log(size)/log(2));
	unsigned int _maxLevel;
	/// The number of triangles in the TBinTree.
	unsigned int _triNo;
	/// Dirty state.
	bool		_dirty;
	/// Max number of bintrees to manage.
	unsigned int _bintreeMax;
	/// Bintree's managed by this mesh
	ddgTBinTree ** _bintree;
	/// A transformed vertex cache.
	ddgVCache		_vcache;
	/// Number of visible triangles in the mesh.
	unsigned int _visTri;
	/// Split queue.
	ddgSplayTree	*_qs;
	/// Merge queue.
	ddgSplayTree	*_qm;
	/// Split queue iterator
	ddgSplayIterator		*_qsi;
	/// Merge queue
	ddgSplayIterator		*_qmi;
	/// Number of rows of bintrees.
	unsigned int	_nr;
	/// Number of columns of bintrees.
	unsigned int	_nc;
    /// World to camera space transformation matrix must be initialized before calling calculate.
    double          *_wtoc;
    /// The bounding box in screen space.
    ddgBBox         *_camBBox;
    /// The field of view.
    float           _tanHalfFOV;
	/// The min number of triangles that should be displayed.
	unsigned int	_mindetail;
	/// The max number of triangles that should be displayed.
	unsigned int	_maxdetail;
	/// Distant clip range triangles beyond this point are not needed.
	float		_farclip;
	/// Near clip range triangles beyond this point are not needed.
	float		_nearclip;
	/// Triangles beyond this point have their priority recalculated once every n frames.
	float		_progDist;
	/// Merge queue active.
	bool		_merge;
	/// Total number of triangles rendered.  For statistics.
	unsigned int _triCount;
	/// Total number of priorities calculated.
	unsigned int _priCount;
	/// Total number of queue insertions.
	unsigned int _insCount;
	/// Total number of queue removals.
	unsigned int _remCount;
	/// Total number of queue updates.
	unsigned int _movCount;
	/// Number of balanceOperations this frame.
	unsigned int _balanceCount;
public:
	/**
     * Constructor, pass in the size of the BinTree.
	 *  s = size along one edge of one BinTree.
	 *  i = image object from which to contruct the mesh.
     */
	ddgTBinMesh( ddgHeightMap *i);
	/// Destroy the Bintree mesh.
	~ddgTBinMesh(void);
	/**
	 * Pointer to an array of MTri objects.
	 */
	ddgMSTri* stri;
	/// Initialize the mesh.
	bool init( double *worldToCameraMatrix, ddgBBox *camClipBox, float fov );
	/**
	 * Initialize the neighbour field of all triangles.
	 */
	void initNeighbours( void );
	/**
	 *  Initialize the vertex and row/col data of the STri. 
	 *  Passed in are the triangles which carry the points
	 *  that describe the current triangle.
	 *  va is immediate parent.
	 *  v1 and v0 are the sub triangles of va. 
	 */
	void initVertex( unsigned int level,
			   ddgTriIndex va,
			   ddgTriIndex v1,
			   ddgTriIndex v0,
			   ddgTriIndex vc);
    /// Return the edge status of a tri.
    unsigned int edge(ddgTriIndex i)
    {
        return stri[i].edge();
    }

	/// Return the required LOD.
	unsigned int mindetail( void ) { return _mindetail; }
	/// Set the required LOD.
	void mindetail( unsigned int d ) { _mindetail = d; }
	/// Return the required LOD.
	unsigned int maxdetail( void ) { return _maxdetail; }
	/// Set the required LOD.
	void maxdetail( unsigned int d ) { _maxdetail = d; }

	/// Function to add a bintree.
	void addBinTree( ddgTBinTree *bt );
	/// Function to remove a bintree.
	void removeBinTree( ddgTBinTree *bt );
	/// Return the bintree for a given index.
	ddgTBinTree *getBinTree( ddgTreeIndex i)
	{ ddgAssert(i < _bintreeMax && i >= 0); return _bintree[i]; }

	/// Return the split queue 
	ddgSplayTree *qs(void) { return _qs; }
	/// Return the merge queue 
	ddgSplayTree *qm(void) { return _qm; }
	/// Return an iterator for the visible set of triangles.
	ddgSplayIterator* qsi(void) { return _qsi; }
	/// Return a priority from the merge queue.
	unsigned int prioritySQ( ddgSplayIterator *i );
	/// Return the tree of an item from the split queue.
	ddgTBinTree* treeSQ( ddgSplayIterator *i )
	{
		return getBinTree(_qs->retrieve(i->current())->tree());
	}
	/// Return an item from the split queue.
	unsigned int indexSQ(ddgSplayIterator *i)
	{
		return  _qs->retrieve(i->current())->index();
	}
	/// Return a priority from the merge queue.
	unsigned int priorityMQ( ddgSplayIterator *i );
	/// Return the tree of an item from the merge queue.
	ddgTBinTree* treeMQ( ddgSplayIterator *i )
	{
		return getBinTree(_qm->retrieve(i->current())->tree());
	}
	/// Return an item from the split queue.
	unsigned int indexMQ(ddgSplayIterator *i)
	{
		return _qm->retrieve(i->current())->index();
	}
	/// Return the number of triangles.
	unsigned int triNo(void) { return _triNo; }
	/**
	 *  Split the best split candidate.
	 */
	bool splitQueue(void);
	/**
	 *  Merge the best merge candidate.
	 */
	bool mergeQueue(void);
	/**
	 *  Balance the split and merge queues.
	 * Returns the number of iterations it took to get to a balanced state.
	 */
	unsigned int balanceQueue(void);
	/// Empty the split queue.
	void clearSQ(void);
	/// Empty the merge queue.
	void clearMQ(void);

	/// Return the number of visible triangles in the mesh.
	unsigned int visTri(void) { return _visTri; }

	/// Recalculate the number of visibile triangles.
	unsigned int updateVisibleTri(void);

	/// Return the number of split levels.
	unsigned int maxLevel( void ) { return _maxLevel; }

	/// Set dirty state.
	void dirty( bool d ) { _dirty = d; }
	/// Get dirty state.
	bool dirty( void ) { return _dirty; }

	/**
	 * Calculate the optimal set of triangles for the mesh at current camera pos.
	 * returns true if any calculation was performed.
	 */
	bool calculate(void);

{'fraction_non_alphanumeric': 0.08844779674473997, 'fraction_numerical': 0.008733624454148471, 'mean_word_length': 2.746430696014277, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4194934', 'n_tokens_mistral': 8070, 'n_tokens_neox': 7598, 'n_words': 3323}