00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <set>
00021 #include <stack>
00022
00023 #include <Types.hpp>
00024 #include <TinyVector.hpp>
00025 #include <TinyMatrix.hpp>
00026
00027 #include <ConnectivityBuilder.hpp>
00028 #include <ConformTransformation.hpp>
00029
00030 #include <P1Triangle3DFiniteElement.hpp>
00031
00032 #include <MeshOfTriangles.hpp>
00033 #include <EdgesBuilder.hpp>
00034
00035 MeshOfTriangles::
00036 MeshOfTriangles(ReferenceCounting<VerticesSet> vertices,
00037 ReferenceCounting<VerticesCorrespondance> correspondances,
00038 ReferenceCounting<Vector<Triangle> > triangles)
00039 : Mesh(Mesh::trianglesMesh,
00040 Mesh::plane,
00041 vertices,
00042 correspondances),
00043 __cells(triangles),
00044 __octree(0),
00045 __connectivity(*this)
00046 {
00047 ;
00048 }
00049
00050 void MeshOfTriangles::buildLocalizationTools()
00051 {
00052 ffout(3) << "Generating localization in triangles mesh...\n";
00053 if (this->numberOfVertices()==0) {
00054 throw ErrorHandler(__FILE__,__LINE__,
00055 "the mesh contains no vertices\n",
00056 ErrorHandler::normal);
00057 }
00058
00059 {
00060
00061
00062 ConnectivityBuilder<MeshOfTriangles> builder(*this);
00063 builder.generates(Connectivity<MeshOfTriangles>::CellToCells);
00064 }
00065
00066
00067 const TinyVector <3,real_t>& v0 = this->vertex(0);
00068 __a[0] = v0[0];
00069 __a[1] = v0[1];
00070 __b = __a;
00071 for (size_t i=1; i<this->numberOfVertices(); ++i) {
00072 Vertex& x = this->vertex(i);
00073 for (size_t k=0; k<2; ++k) {
00074 __a[k] = (__a[k]<x[k])?__a[k]:x[k];
00075 __b[k] = (__b[k]>x[k])?__b[k]:x[k];
00076 }
00077 }
00078 ffout(3) << "- Bounding box is " << __a << ',' << __b << '\n';
00079
00080 ffout(3) << "- Building the octree\n";
00081 __octree = new Octree<size_t, 2>(__a,__b);
00082
00083 for (size_t i = 0; i < this->numberOfCells(); ++i) {
00084 ConformTransformationP1Triangle T(this->cell(i));
00085
00086 TinyVector<3,real_t> X;
00087 T.value(P1Triangle3DFiniteElement::massCenter(), X);
00088
00089 TinyVector<2,real_t> x;
00090 x[0]=X[0];
00091 x[1]=X[1];
00092
00093 __octree->add(i,x);
00094 }
00095 ffout(3) << "Generating localization in triangles mesh: done\n";
00096 }
00097
00098 MeshOfTriangles::const_iterator
00099 MeshOfTriangles::find(const double& x,
00100 const double& y,
00101 const double& z) const
00102 {
00103 if (__octree == 0) {
00104 const_cast<MeshOfTriangles*>(this)->buildLocalizationTools();
00105 }
00106
00107
00108 TinyVector<2,real_t> X;
00109 X[0] = x;
00110 X[1] = y;
00111 Octree<size_t, 2>::iterator i = __octree->fuzzySearch(X);
00112
00113 size_t guessedCellNumber = (*i).value();
00114 const_iterator t0(*this, guessedCellNumber);
00115
00116 bool found=false;
00117
00118 std::set<MeshOfTriangles::const_iterator> visited;
00119 std::set<MeshOfTriangles::const_iterator> toVisitSet;
00120 std::stack<MeshOfTriangles::const_iterator> toVisitStack;
00121
00122 toVisitSet.insert(t0);
00123 toVisitStack.push(t0);
00124 const_iterator c (*this);
00125
00126 do {
00127
00128 c = toVisitStack.top();
00129
00130 toVisitSet.erase(c);
00131 toVisitStack.pop();
00132 visited.insert(c);
00133
00134 const Triangle& t = *c;
00135
00136 TinyVector<3, real_t> lambda;
00137
00138 t.getBarycentricCoordinates(X, lambda);
00139
00140 found = true;
00141 for (size_t i=0; i<3; ++i) {
00142 #warning Should use a relevent epsilon here ...
00143 if (lambda[i] < -1E-6) {
00144 found = false;
00145 const Triangle* newT = __connectivity.cells(t)[i];
00146 if (newT != 0) {
00147 const_iterator t1(*this, this->cellNumber(*newT));
00148
00149 if (visited.find(t1) == visited.end()) {
00150 if (toVisitSet.find(t1) == toVisitSet.end()) {
00151 toVisitSet.insert(t1);
00152 toVisitStack.push(t1);
00153 }
00154 }
00155 }
00156 }
00157 }
00158 } while (not(found) and not(toVisitStack.empty()));
00159
00160 if (not(found)) {
00161 c = const_iterator(*this,const_iterator::End);
00162 }
00163 return c;
00164 }
00165