00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef MESH_EXTRACTOR_HPP
00021 #define MESH_EXTRACTOR_HPP
00022
00023 #include <ReferenceCounting.hpp>
00024 #include <CellDuplicator.hpp>
00025
00026 #include <ErrorHandler.hpp>
00027
00028 #include <sstream>
00029 #include <set>
00030
00041 template <typename MeshType>
00042 struct CopyBackgroundMesh
00043 {
00044 static void copy(const MeshType& originalMesh,
00045 MeshType* m)
00046 {
00047 ;
00048 }
00049 };
00050
00051 template <>
00052 struct CopyBackgroundMesh<SurfaceMeshOfTriangles>
00053 {
00054 static void copy(const SurfaceMeshOfTriangles& originalMesh,
00055 SurfaceMeshOfTriangles* m)
00056 {
00057 m->setBackgroundMesh(originalMesh.backgroundMesh());
00058 }
00059 };
00060
00061 template <>
00062 struct CopyBackgroundMesh<SurfaceMeshOfQuadrangles>
00063 {
00064 static void copy(const SurfaceMeshOfQuadrangles& originalMesh,
00065 SurfaceMeshOfQuadrangles* m)
00066 {
00067 m->setBackgroundMesh(originalMesh.backgroundMesh());
00068 }
00069 };
00070
00071
00072 template <typename MeshType>
00073 class MeshExtractor
00074 {
00075 private:
00076 ConstReferenceCounting<MeshType> __originalMesh;
00078 public:
00086 MeshType*
00087 operator()(const std::set<size_t>& referencesSet) const
00088 {
00089 typedef typename MeshType::CellType CellType;
00090
00091 typedef std::map<const Vertex*, size_t> KeptVertices;
00092 KeptVertices keptVertices;
00093
00094 typedef std::set<size_t> KeptCells;
00095 KeptCells keptCells;
00096
00097 size_t vertexNumber = 0;
00098
00099 for (typename MeshType::const_iterator icell(*__originalMesh);
00100 not(icell.end()); ++icell) {
00101 const CellType& cell = *icell;
00102 if (referencesSet.find(cell.reference()) != referencesSet.end()) {
00103 keptCells.insert(__originalMesh->cellNumber(cell));
00104 for (size_t i=0; i<MeshType::CellType::NumberOfVertices; ++i) {
00105 if (keptVertices.find(&cell(i)) == keptVertices.end()) {
00106 keptVertices[&cell(i)] = vertexNumber;
00107 ++vertexNumber;
00108 }
00109 }
00110 }
00111 }
00112
00113 if (keptCells.size() == 0) {
00114 std::stringstream errorMsg;
00115 errorMsg << "no cell has reference that matches (";
00116 KeptCells::const_iterator i = referencesSet.begin();
00117 errorMsg << *i;
00118 for (;i != referencesSet.end(); ++i) {
00119 errorMsg << ',' << *i;
00120 }
00121 errorMsg << ")!" << std::ends;
00122 throw ErrorHandler(__FILE__,__LINE__,
00123 errorMsg.str(),
00124 ErrorHandler::normal);
00125 }
00126
00127
00128 ReferenceCounting<VerticesSet> pVerticesSet
00129 = new VerticesSet(keptVertices.size());
00130 VerticesSet& verticesSet = *pVerticesSet;
00131 for (KeptVertices::const_iterator ivertex = keptVertices.begin();
00132 ivertex != keptVertices.end(); ++ivertex) {
00133 verticesSet[ivertex->second] = *ivertex->first;
00134 }
00135
00136 ReferenceCounting<Vector<CellType> > pCellList
00137 = new Vector<CellType>(keptCells.size());
00138 Vector<CellType>& cellList = *pCellList;
00139
00140 size_t n=0;
00141 for (KeptCells::const_iterator i = keptCells.begin();
00142 i != keptCells.end(); ++i, ++n) {
00143 const CellType& cell = __originalMesh->cell(*i);
00144 cellList[n] = CellDuplicator<CellType>(cell, keptVertices, verticesSet);
00145 }
00146
00147 MeshType* m = new MeshType(pVerticesSet,
00148 new VerticesCorrespondance(pVerticesSet->numberOfVertices()),
00149 pCellList);
00150
00151 CopyBackgroundMesh<MeshType>::copy(*__originalMesh, m);
00152
00153 return m;
00154 }
00155
00161 MeshExtractor(ConstReferenceCounting<MeshType> m)
00162 : __originalMesh(m)
00163 {
00164 ;
00165 }
00166
00172 MeshExtractor(const MeshExtractor& m)
00173 : __originalMesh(m.__originalMesh)
00174 {
00175 ;
00176 }
00177
00182 ~MeshExtractor()
00183 {
00184 ;
00185 }
00186 };
00187
00188 #endif // MESH_EXTRACTOR_HPP