00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SG_TRIANGLE_BIN_HXX
00023 #define SG_TRIANGLE_BIN_HXX
00024
00025 #include <vector>
00026 #include <map>
00027 #include "SGVertexArrayBin.hxx"
00028
00029 template<typename T>
00030 class SGTriangleBin : public SGVertexArrayBin<T> {
00031 public:
00032 #define BUILD_EDGE_MAP
00033 typedef typename SGVertexArrayBin<T>::value_type value_type;
00034 typedef typename SGVertexArrayBin<T>::index_type index_type;
00035 typedef SGVec2<index_type> edge_ref;
00036 typedef SGVec3<index_type> triangle_ref;
00037 typedef std::vector<triangle_ref> TriangleVector;
00038 typedef std::vector<index_type> TriangleList;
00039 typedef std::map<edge_ref,TriangleList> EdgeMap;
00040
00041 void insert(const value_type& v0, const value_type& v1, const value_type& v2)
00042 {
00043 index_type i0 = SGVertexArrayBin<T>::insert(v0);
00044 index_type i1 = SGVertexArrayBin<T>::insert(v1);
00045 index_type i2 = SGVertexArrayBin<T>::insert(v2);
00046 index_type triangleIndex = _triangleVector.size();
00047 _triangleVector.push_back(triangle_ref(i0, i1, i2));
00048 #ifdef BUILD_EDGE_MAP
00049 _edgeMap[edge_ref(i0, i1)].push_back(triangleIndex);
00050 _edgeMap[edge_ref(i1, i2)].push_back(triangleIndex);
00051 _edgeMap[edge_ref(i2, i0)].push_back(triangleIndex);
00052 #endif
00053 }
00054
00055 unsigned getNumTriangles() const
00056 { return _triangleVector.size(); }
00057 const triangle_ref& getTriangleRef(index_type i) const
00058 { return _triangleVector[i]; }
00059 const TriangleVector& getTriangles() const
00060 { return _triangleVector; }
00061
00062 #ifdef BUILD_EDGE_MAP
00063
00064 void getConnectedSets(std::list<TriangleVector>& connectSets) const
00065 {
00066 std::vector<bool> processedTriangles(getNumTriangles(), false);
00067 for (index_type i = 0; i < getNumTriangles(); ++i) {
00068 if (processedTriangles[i])
00069 continue;
00070
00071 TriangleVector currentSet;
00072 std::vector<edge_ref> edgeStack;
00073
00074 {
00075 triangle_ref triangleRef = getTriangleRef(i);
00076 edgeStack.push_back(edge_ref(triangleRef[0], triangleRef[1]));
00077 edgeStack.push_back(edge_ref(triangleRef[1], triangleRef[2]));
00078 edgeStack.push_back(edge_ref(triangleRef[2], triangleRef[0]));
00079 currentSet.push_back(triangleRef);
00080 processedTriangles[i] = true;
00081 }
00082
00083 while (!edgeStack.empty()) {
00084 edge_ref edge = edgeStack.back();
00085 edgeStack.pop_back();
00086
00087 typename EdgeMap::const_iterator emiList[2] = {
00088 _edgeMap.find(edge),
00089 _edgeMap.find(edge_ref(edge[1], edge[0]))
00090 };
00091 for (unsigned ei = 0; ei < 2; ++ei) {
00092 typename EdgeMap::const_iterator emi = emiList[ei];
00093 if (emi == _edgeMap.end())
00094 continue;
00095
00096 for (unsigned ti = 0; ti < emi->second.size(); ++ti) {
00097 index_type triangleIndex = emi->second[ti];
00098 if (processedTriangles[triangleIndex])
00099 continue;
00100
00101 triangle_ref triangleRef = getTriangleRef(triangleIndex);
00102 edgeStack.push_back(edge_ref(triangleRef[0], triangleRef[1]));
00103 edgeStack.push_back(edge_ref(triangleRef[1], triangleRef[2]));
00104 edgeStack.push_back(edge_ref(triangleRef[2], triangleRef[0]));
00105 currentSet.push_back(triangleRef);
00106 processedTriangles[triangleIndex] = true;
00107 }
00108 }
00109 }
00110
00111 connectSets.push_back(currentSet);
00112 }
00113 }
00114 #endif
00115
00116 private:
00117 TriangleVector _triangleVector;
00118 #ifdef BUILD_EDGE_MAP
00119 EdgeMap _edgeMap;
00120 #endif
00121 };
00122
00123 #endif