1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM 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 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 A surface analysis tool which sub-sets the triSurface
27 to choose only a part of interest. Based on subsetMesh.
29 \*---------------------------------------------------------------------------*/
31 #include "triSurface.H"
36 #include "IOdictionary.H"
38 #include "indexedOctree.H"
40 #include "treeDataTriSurface.H"
45 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 int main(int argc, char *argv[])
50 argList::noParallel();
51 argList::validArgs.clear();
52 argList::validArgs.append("surfaceSubsetDict");
53 argList::validArgs.append("surface file");
54 argList::validArgs.append("output file");
55 argList args(argc, argv);
57 Info<< "Reading dictionary " << args.additionalArgs()[0] << " ..." << endl;
58 IFstream dictFile(args.additionalArgs()[0]);
59 dictionary meshSubsetDict(dictFile);
61 Info<< "Reading surface " << args.additionalArgs()[1] << " ..." << endl;
62 triSurface surf1(args.additionalArgs()[1]);
64 Info<< "Original:" << endl;
65 surf1.writeStats(Info);
69 labelList markedPoints
71 meshSubsetDict.lookup("localPoints")
76 meshSubsetDict.lookup("edges")
81 meshSubsetDict.lookup("faces")
86 meshSubsetDict.lookup("zone")
89 if ((markedZone.size() != 0) && (markedZone.size() != 2))
91 FatalErrorIn(args.executable())
92 << "zone specification should be two points, min and max of "
93 << "the boundingbox" << endl
94 << "zone:" << markedZone
98 Switch addFaceNeighbours
100 meshSubsetDict.lookup("addFaceNeighbours")
103 // Mark the cells for the subset
106 boolList facesToSubset(surf1.size(), false);
110 // pick up faces connected to "localPoints"
113 if (markedPoints.size() > 0)
115 Info << "Found " << markedPoints.size() << " marked point(s)." << endl;
117 // pick up cells sharing the point
119 forAll (markedPoints, pointI)
123 markedPoints[pointI] < 0
124 || markedPoints[pointI] >= surf1.nPoints()
127 FatalErrorIn(args.executable())
128 << "localPoint label " << markedPoints[pointI]
130 << " The mesh has got "
131 << surf1.nPoints() << " localPoints."
135 const labelList& curFaces =
136 surf1.pointFaces()[markedPoints[pointI]];
140 facesToSubset[curFaces[i]] = true;
148 // pick up faces connected to "edges"
151 if (markedEdges.size() > 0)
153 Info << "Found " << markedEdges.size() << " marked edge(s)." << endl;
155 // pick up cells sharing the edge
157 forAll (markedEdges, edgeI)
161 markedEdges[edgeI] < 0
162 || markedEdges[edgeI] >= surf1.nEdges()
165 FatalErrorIn(args.executable())
166 << "edge label " << markedEdges[edgeI]
168 << " The mesh has got "
169 << surf1.nEdges() << " edges."
173 const labelList& curFaces = surf1.edgeFaces()[markedEdges[edgeI]];
177 facesToSubset[curFaces[i]] = true;
184 // pick up faces with centre inside "zone"
187 if (markedZone.size() == 2)
189 const point& min = markedZone[0];
190 const point& max = markedZone[1];
192 Info << "Using zone min:" << min << " max:" << max << endl;
196 const labelledTri& f = surf1[faceI];
197 const point centre = f.centre(surf1.points());
201 (centre.x() >= min.x())
202 && (centre.y() >= min.y())
203 && (centre.z() >= min.z())
204 && (centre.x() <= max.x())
205 && (centre.y() <= max.y())
206 && (centre.z() <= max.z())
209 facesToSubset[faceI] = true;
216 // pick up faces on certain side of surface
219 if (meshSubsetDict.found("surface"))
221 const dictionary& surfDict = meshSubsetDict.subDict("surface");
223 fileName surfName(surfDict.lookup("name"));
225 Switch outside(surfDict.lookup("outside"));
229 Info<< "Selecting all triangles with centre outside surface "
234 Info<< "Selecting all triangles with centre inside surface "
238 // Read surface to select on
239 triSurface selectSurf(surfName);
242 treeBoundBox bb(selectSurf.localPoints());
244 // Radnom number generator
245 Random rndGen(354543);
248 indexedOctree<treeDataTriSurface> selectTree
250 treeDataTriSurface(selectSurf),
251 bb.extend(rndGen, 1E-3), // slightly randomize bb
257 // Check if face (centre) is in outside or inside.
258 forAll(facesToSubset, faceI)
260 if (!facesToSubset[faceI])
262 const point fc(surf1[faceI].centre(surf1.points()));
264 indexedOctree<treeDataTriSurface>::volumeType t =
265 selectTree.getVolumeType(fc);
267 if (t == indexedOctree<treeDataTriSurface>::INSIDE && !outside)
269 facesToSubset[faceI] = true;
273 t == indexedOctree<treeDataTriSurface>::OUTSIDE
277 facesToSubset[faceI] = true;
285 // pick up specified "faces"
288 // Number of additional faces picked up because of addFaceNeighbours
289 label nFaceNeighbours = 0;
291 if (markedFaces.size() > 0)
293 Info << "Found " << markedFaces.size() << " marked face(s)." << endl;
295 // Check and mark faces to pick up
296 forAll (markedFaces, faceI)
300 markedFaces[faceI] < 0
301 || markedFaces[faceI] >= surf1.size()
304 FatalErrorIn(args.executable())
305 << "Face label " << markedFaces[faceI] << "out of range."
306 << " The mesh has got "
307 << surf1.size() << " faces."
312 facesToSubset[markedFaces[faceI]] = true;
314 // mark its neighbours if requested
315 if (addFaceNeighbours)
317 const labelList& curFaces =
318 surf1.faceFaces()[markedFaces[faceI]];
322 label faceI = curFaces[i];
324 if (!facesToSubset[faceI])
326 facesToSubset[faceI] = true;
334 if (addFaceNeighbours)
336 Info<< "Added " << nFaceNeighbours
337 << " faces because of addFaceNeighbours" << endl;
340 // Create subsetted surface
345 surf1.subsetMesh(facesToSubset, pointMap, faceMap)
348 Info<< "Subset:" << endl;
349 surf2.writeStats(Info);
352 fileName outFileName(args.additionalArgs()[2]);
354 Info << "Writing surface to " << outFileName << endl;
356 surf2.write(outFileName);
362 // ************************************************************************* //