FreeFOAM The Cross-Platform CFD Toolkit
surfaceAdd.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
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
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Application
25  surfaceAdd
26 
27 Description
28  Add two surfaces. Does geometric merge on points. Does not check for
29  overlapping/intersecting triangles.
30 
31  Keeps patches separate by renumbering.
32 
33 Usage
34 
35  - surfaceAdd [OPTIONS] <Foam surface file> <Foam surface file> <Foam output surface file>
36 
37  @param <Foam surface file> \n
38  @todo Detailed description of argument.
39 
40  @param <Foam surface file> \n
41  @todo Detailed description of argument.
42 
43  @param <Foam output surface file> \n
44  @todo Detailed description of argument.
45 
46  @param -points <pointsFile>\n
47  Add points from file.
48 
49  @param -mergeRegions \n
50  Merge the regions.
51 
52  @param -case <dir>\n
53  Case directory.
54 
55  @param -help \n
56  Display help message.
57 
58  @param -doc \n
59  Display Doxygen API documentation page for this application.
60 
61  @param -srcDoc \n
62  Display Doxygen source documentation page for this application.
63 
64 \*---------------------------------------------------------------------------*/
65 
66 #include <OpenFOAM/argList.H>
67 #include <OpenFOAM/fileName.H>
68 #include <triSurface/triSurface.H>
69 #include <OpenFOAM/OFstream.H>
70 #include <OpenFOAM/IFstream.H>
71 #include <OpenFOAM/triFace.H>
72 #include <OpenFOAM/triFaceList.H>
73 
74 using namespace Foam;
75 
76 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
77 
78 // Main program:
79 
80 int main(int argc, char *argv[])
81 {
84  argList::validArgs.append("Foam surface file");
85  argList::validArgs.append("Foam surface file");
86  argList::validArgs.append("Foam output file");
87  argList::validOptions.insert("points", "pointsFile");
88  argList::validOptions.insert("mergeRegions", "");
89  argList args(argc, argv);
90 
91  fileName inFileName1(args.additionalArgs()[0]);
92  fileName inFileName2(args.additionalArgs()[1]);
93  fileName outFileName(args.additionalArgs()[2]);
94 
95  bool addPoint = args.optionFound("points");
96  bool mergeRegions = args.optionFound("mergeRegions");
97 
98  if (addPoint)
99  {
100  Info<< "Reading a surface and adding points from a file"
101  << "; merging the points and writing the surface to another file"
102  << nl << endl;
103 
104  Info<< "Surface : " << inFileName1<< nl
105  << "Points : " << args.option("points") << nl
106  << "Writing : " << outFileName << nl << endl;
107  }
108  else
109  {
110  Info<< "Reading two surfaces"
111  << "; merging points and writing the surface to another file"
112  << nl << endl;
113 
114  if (mergeRegions)
115  {
116  Info<< "Regions from the two files will get merged" << nl
117  << "Do not use this option if you want to keep the regions"
118  << " separate" << nl << endl;
119  }
120  else
121  {
122  Info<< "Regions from the two files will not get merged" << nl
123  << "Regions from " << inFileName2 << " will get offset so"
124  << " as not to overlap with the regions in " << inFileName1
125  << nl << endl;
126  }
127 
128 
129  Info<< "Surface1 : " << inFileName1<< nl
130  << "Surface2 : " << inFileName2<< nl
131  << "Writing : " << outFileName << nl << endl;
132  }
133 
134  const triSurface surface1(inFileName1);
135 
136  Info<< "Surface1:" << endl;
137  surface1.writeStats(Info);
138  Info<< endl;
139 
140  const pointField& points1 = surface1.points();
141 
142  // Final surface
143  triSurface combinedSurf;
144 
145  if (addPoint)
146  {
147  IFstream pointsFile(args.option("points"));
148  pointField extraPoints(pointsFile);
149 
150  Info<< "Additional Points:" << extraPoints.size() << endl;
151 
152  vectorField pointsAll(points1);
153  label pointI = pointsAll.size();
154  pointsAll.setSize(pointsAll.size() + extraPoints.size());
155 
156  forAll(extraPoints, i)
157  {
158  pointsAll[pointI++] = extraPoints[i];
159  }
160 
161  combinedSurf = triSurface(surface1, surface1.patches(), pointsAll);
162  }
163  else
164  {
165  const triSurface surface2(inFileName2);
166 
167  Info<< "Surface2:" << endl;
168  surface2.writeStats(Info);
169  Info<< endl;
170 
171 
172  // Make new storage
173  List<labelledTri> facesAll(surface1.size() + surface2.size());
174 
175  const pointField& points2 = surface2.points();
176 
177  vectorField pointsAll(points1.size() + points2.size());
178 
179 
180  label pointi = 0;
181  // Copy points1 into pointsAll
182  forAll(points1, point1i)
183  {
184  pointsAll[pointi++] = points1[point1i];
185  }
186  // Add surface2 points
187  forAll(points2, point2i)
188  {
189  pointsAll[pointi++] = points2[point2i];
190  }
191 
192 
193  label trianglei = 0;
194 
195  // Copy triangles1 into trianglesAll
196  forAll(surface1, faceI)
197  {
198  facesAll[trianglei++] = surface1[faceI];
199  }
200  label nRegions1 = surface1.patches().size();
201 
202 
203  if (!mergeRegions)
204  {
205  Info<< "Surface " << inFileName1 << " has " << nRegions1
206  << " regions"
207  << nl
208  << "All region numbers in " << inFileName2 << " will be offset"
209  << " by this amount" << nl << endl;
210  }
211 
212  // Add (renumbered) surface2 triangles
213  forAll(surface2, faceI)
214  {
215  const labelledTri& tri = surface2[faceI];
216 
217  labelledTri& destTri = facesAll[trianglei++];
218  destTri[0] = tri[0] + points1.size();
219  destTri[1] = tri[1] + points1.size();
220  destTri[2] = tri[2] + points1.size();
221  if (mergeRegions)
222  {
223  destTri.region() = tri.region();
224  }
225  else
226  {
227  destTri.region() = tri.region() + nRegions1;
228  }
229  }
230 
231  label nRegions2 = surface2.patches().size();
232 
233  geometricSurfacePatchList newPatches;
234 
235  if (mergeRegions)
236  {
237  // Overwrite
238  newPatches.setSize(max(nRegions1, nRegions2));
239 
240  forAll(surface1.patches(), patchI)
241  {
242  newPatches[patchI] = surface1.patches()[patchI];
243  }
244  forAll(surface2.patches(), patchI)
245  {
246  newPatches[patchI] = surface2.patches()[patchI];
247  }
248  }
249  else
250  {
251  Info<< "Regions from " << inFileName2 << " have been renumbered:"
252  << nl
253  << " old\tnew" << nl;
254 
255  for (label regionI = 0; regionI < nRegions2; regionI++)
256  {
257  Info<< " " << regionI << '\t' << regionI+nRegions1
258  << nl;
259  }
260  Info<< nl;
261 
262  newPatches.setSize(nRegions1 + nRegions2);
263 
264  label newPatchI = 0;
265 
266  forAll(surface1.patches(), patchI)
267  {
268  newPatches[newPatchI++] = surface1.patches()[patchI];
269  }
270 
271  forAll(surface2.patches(), patchI)
272  {
273  newPatches[newPatchI++] = surface2.patches()[patchI];
274  }
275  }
276 
277 
278  Info<< "New patches:" << nl;
279  forAll(newPatches, patchI)
280  {
281  Info<< " " << patchI << '\t' << newPatches[patchI].name() << nl;
282  }
283  Info<< endl;
284 
285 
286  // Construct new surface mesh
287  combinedSurf = triSurface(facesAll, newPatches, pointsAll);
288  }
289 
290  // Merge all common points and do some checks
291  combinedSurf.cleanup(true);
292 
293  Info<< "Merged surface:" << endl;
294 
295  combinedSurf.writeStats(Info);
296 
297  Info<< endl;
298 
299  Info << "Writing : " << outFileName << endl;
300 
301  // No need to 'group' while writing since all in correct order anyway.
302  combinedSurf.write(outFileName);
303 
304  Info << "End\n" << endl;
305 
306  return 0;
307 }
308 
309 
310 // ************************ vim: set sw=4 sts=4 et: ************************ //