1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
25 Checks topology of the patch.
27 \*---------------------------------------------------------------------------*/
29 #include "PrimitivePatchTemplate.H"
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 template<class> class FaceList,
44 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
48 const labelList& pFaces,
49 const label startFaceI,
50 const label startEdgeI,
54 label index = findIndex(pFaces, startFaceI);
56 if (!pFacesHad[index])
58 // Mark face as been visited.
59 pFacesHad[index] = true;
61 // Step to next edge on face which is still using pointI
62 const labelList& fEdges = faceEdges()[startFaceI];
68 label edgeI = fEdges[i];
70 const edge& e = edges()[edgeI];
72 if (edgeI != startEdgeI && (e[0] == pointI || e[1] == pointI))
84 "PrimitivePatch<Face, FaceList, PointField, PointType>::"
86 ) << "Problem: cannot find edge out of " << fEdges
87 << "on face " << startFaceI << " that uses point " << pointI
88 << " and is not edge " << startEdgeI << abort(FatalError);
91 // Walk to next face(s) across edge.
92 const labelList& eFaces = edgeFaces()[nextEdgeI];
96 if (eFaces[i] != startFaceI)
112 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
117 template<class> class FaceList,
121 typename Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::surfaceTopo
122 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
127 Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
129 "calculating patch topology"
133 const labelListList& edgeFcs = edgeFaces();
135 surfaceTopo pType = MANIFOLD;
137 forAll(edgeFcs, edgeI)
139 label nNbrs = edgeFcs[edgeI].size();
141 if (nNbrs < 1 || nNbrs > 2)
145 // Can exit now. Surface is illegal.
150 // Surface might be open or illegal so keep looping.
157 Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
159 "finished calculating patch topology"
170 template<class> class FaceList,
175 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
184 Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
185 "checkTopology(const bool, labelHashSet&) : "
186 "checking patch topology"
192 const labelListList& edgeFcs = edgeFaces();
194 surfaceTopo surfaceType = MANIFOLD;
196 forAll(edgeFcs, edgeI)
198 label nNbrs = edgeFcs[edgeI].size();
200 if (nNbrs < 1 || nNbrs > 2)
202 surfaceType = ILLEGAL;
206 Info<< "Edge " << edgeI << " with vertices:" << edges()[edgeI]
207 << " has " << nNbrs << " face neighbours"
213 const edge& e = edges()[edgeI];
215 setPtr->insert(meshPoints()[e.start()]);
216 setPtr->insert(meshPoints()[e.end()]);
227 Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::"
228 "checkTopology(const bool, labelHashSet&) : "
229 "finished checking patch topology"
233 return surfaceType == ILLEGAL;
240 template<class> class FaceList,
245 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
252 const labelListList& pf = pointFaces();
253 const labelListList& pe = pointEdges();
254 const labelListList& ef = edgeFaces();
255 const labelList& mp = meshPoints();
257 bool foundError = false;
261 const labelList& pFaces = pf[pointI];
263 // Visited faces (as indices into pFaces)
264 boolList pFacesHad(pFaces.size(), false);
267 const labelList& pEdges = pe[pointI];
268 label startEdgeI = pEdges[0];
270 const labelList& eFaces = ef[startEdgeI];
274 // Visit all faces using pointI, starting from eFaces[i] and
275 // startEdgeI. Mark off all faces visited in pFacesHad.
276 this->visitPointRegion
280 eFaces[i], // starting face for walk
281 startEdgeI, // starting edge for walk
286 // After this all faces using pointI should have been visited and
287 // marked off in pFacesHad.
289 label unset = findIndex(pFacesHad, false);
295 label meshPointI = mp[pointI];
299 setPtr->insert(meshPointI);
304 Info<< "Point " << meshPointI
305 << " uses faces which are not connected through an edge"
307 << "This means that the surface formed by this patched"
308 << " is multiply connected at this point" << nl
309 << "Connected (patch) faces:" << nl;
315 Info<< " " << pFaces[i] << endl;
319 Info<< nl << "Unconnected (patch) faces:" << nl;
324 Info<< " " << pFaces[i] << endl;
338 template<class> class FaceList,
343 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
346 const fileName& name,
347 const FaceListType& faces,
348 const Field<PointType>& points
351 // Write patch and points into VTK
352 OFstream mps(name + ".vtk");
354 mps << "# vtk DataFile Version 2.0" << nl
355 << name << ".vtk" << nl
357 << "DATASET POLYDATA" << nl
358 << "POINTS " << points.size() << " float" << nl;
361 List<float> mlpBuffer(3*points.size());
366 mlpBuffer[counter++] = float(points[i].x());
367 mlpBuffer[counter++] = float(points[i].y());
368 mlpBuffer[counter++] = float(points[i].z());
371 forAll (mlpBuffer, i)
373 mps << mlpBuffer[i] << ' ';
375 if (i > 0 && (i % 10) == 0)
382 label nFaceVerts = 0;
384 forAll (faces, faceI)
386 nFaceVerts += faces[faceI].size() + 1;
388 labelList mlfBuffer(nFaceVerts);
391 forAll (faces, faceI)
393 const Face& f = faces[faceI];
395 mlfBuffer[counter++] = f.size();
399 mlfBuffer[counter++] = f[fpI];
404 mps << "POLYGONS " << faces.size() << ' ' << nFaceVerts << endl;
406 forAll (mlfBuffer, i)
408 mps << mlfBuffer[i] << ' ';
410 if (i > 0 && (i % 10) == 0)
422 template<class> class FaceList,
427 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
430 const fileName& name,
431 const FaceListType& faces,
432 const Field<PointType>& points
435 // Write patch and points into VTK
436 OFstream mps(name + ".vtk");
438 mps << "# vtk DataFile Version 2.0" << nl
439 << name << ".vtk" << nl
441 << "DATASET POLYDATA" << nl
442 << "POINTS " << faces.size() << " float" << nl;
445 List<float> mlPointBuffer(3*faces.size());
450 const vector c = faces[i].centre(points);
452 mlPointBuffer[counter++] = float(c.x());
453 mlPointBuffer[counter++] = float(c.y());
454 mlPointBuffer[counter++] = float(c.z());
457 forAll (mlPointBuffer, i)
459 mps << mlPointBuffer[i] << ' ';
461 if (i > 0 && (i % 10) == 0)
469 mps << "POINT_DATA " << faces.size() << nl
470 << "FIELD attributes " << 1 << nl
471 << "normals" << " 3 "
472 << faces.size() << " float" << nl;
474 List<float> mlNormalBuffer(3*faces.size());
479 const vector n = faces[i].normal(points);
481 mlNormalBuffer[counter++] = float(n.x());
482 mlNormalBuffer[counter++] = float(n.y());
483 mlNormalBuffer[counter++] = float(n.z());
486 forAll (mlNormalBuffer, i)
488 mps << mlNormalBuffer[i] << ' ';
490 if (i > 0 && (i % 10) == 0)
502 template<class> class FaceList,
507 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
513 PrimitivePatch<Face, FaceList, PointField, PointType>::writeVTK
525 template<class> class FaceList,
530 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
536 PrimitivePatch<Face, FaceList, PointField, PointType>::writeVTKNormals
545 // ************************************************************************* //