Files
SingularityViewer/indra/libhacd/hacdMeshDecimator.h
2013-01-13 03:23:56 +01:00

117 lines
4.8 KiB
C++

/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef HACD_MESH_DECEMATOR_H
#define HACD_MESH_DECEMATOR_H
#include <queue>
#include <set>
#include <vector>
#include <limits>
#include "hacdVersion.h"
#include "hacdVector.h"
#include "hacdSArray.h"
#include "hacdHACD.h"
namespace HACD
{
typedef double Float;
struct MDVertex
{
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_edges;
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_triangles;
Float m_Q[10];
// 0 1 2 3
// 4 5 6
// 7 8
// 9
bool m_tag;
bool m_onBoundary;
};
struct MDEdge
{
long m_v1;
long m_v2;
double m_qem;
Vec3<Float> m_pos;
bool m_onBoundary;
bool m_tag;
};
struct MDEdgePriorityQueue
{
long m_name;
double m_qem;
inline friend bool operator<(const MDEdgePriorityQueue & lhs, const MDEdgePriorityQueue & rhs) { return (lhs.m_qem > rhs.m_qem);}
inline friend bool operator>(const MDEdgePriorityQueue & lhs, const MDEdgePriorityQueue & rhs) { return (lhs.m_qem < rhs.m_qem);}
};
class MeshDecimator
{
public:
//! Sets the call-back function
//! @param callBack pointer to the call-back function
void SetCallBack(CallBackFunction callBack) { m_callBack = callBack;}
//! Gives the call-back function
//! @return pointer to the call-back function
const CallBackFunction GetCallBack() const { return m_callBack;}
inline void SetEColManifoldConstraint(bool ecolManifoldConstraint) { m_ecolManifoldConstraint = ecolManifoldConstraint; }
inline size_t GetNVertices()const {return m_nVertices;};
inline size_t GetNTriangles() const {return m_nTriangles;};
inline size_t GetNEdges() const {return m_nEdges;};
void GetMeshData(Vec3<Float> * points, Vec3<long> * triangles) const;
void ReleaseMemory();
void Initialize(size_t nVertices, size_t nTriangles,
Vec3<Float> * points,
Vec3<long> * triangles);
bool Decimate(size_t targetNVertices = 100,
size_t targetNTriangles = 0,
double targetError = std::numeric_limits<double>::max());
MeshDecimator(void);
~MeshDecimator(void);
private :
void EdgeCollapse(long v1, long v2);
long GetTriangle(long v1, long v2, long v3) const;
long GetEdge(long v1, long v2) const;
long IsBoundaryEdge(long v1, long v2) const;
bool IsBoundaryVertex(long v) const;
void InitializePriorityQueue();
void InitializeQEM();
bool ManifoldConstraint(long v1, long v2) const;
double ComputeEdgeCost(long v1, long v2, Vec3<Float> & pos) const;
bool EdgeCollapse(double & error);
private:
Vec3<long> * m_triangles;
Vec3<Float> * m_points;
size_t m_nPoints;
size_t m_nInitialTriangles;
size_t m_nVertices;
size_t m_nTriangles;
size_t m_nEdges;
double m_diagBB;
std::vector<MDVertex> m_vertices;
std::vector<MDEdge> m_edges;
std::priority_queue<
MDEdgePriorityQueue,
std::vector<MDEdgePriorityQueue>,
std::less<MDEdgePriorityQueue> > m_pqueue;
CallBackFunction m_callBack; //>! call-back function
bool * m_trianglesTags;
bool m_ecolManifoldConstraint;
};
}
#endif