Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / applications / utilities / surface / surfaceAdd / surfaceAdd.C
blobef00753c3ed81d7eaf44ee95a06ba4abf2bf45e0
1 /*---------------------------------------------------------------------------*\
2   =========                 |
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 -------------------------------------------------------------------------------
8 License
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/>.
24 Description
25     Add two surfaces. Does geometric merge on points. Does not check for
26     overlapping/intersecting triangles.
28     Keeps patches separate by renumbering.
30 \*---------------------------------------------------------------------------*/
32 #include "argList.H"
33 #include "fileName.H"
34 #include "triSurface.H"
35 #include "OFstream.H"
36 #include "IFstream.H"
37 #include "triFace.H"
38 #include "triFaceList.H"
40 using namespace Foam;
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 // Main program:
46 int main(int argc, char *argv[])
48     argList::noParallel();
49     argList::validArgs.clear();
50     argList::validArgs.append("Foam surface file");
51     argList::validArgs.append("Foam surface file");
52     argList::validArgs.append("Foam output file");
53     argList::validOptions.insert("points", "pointsFile");
54     argList::validOptions.insert("mergeRegions", "");
55     argList args(argc, argv);
57     fileName inFileName1(args.additionalArgs()[0]);
58     fileName inFileName2(args.additionalArgs()[1]);
59     fileName outFileName(args.additionalArgs()[2]);
61     bool addPoint = args.optionFound("points");
62     bool mergeRegions = args.optionFound("mergeRegions");
64     if (addPoint)
65     {
66         Info<< "Reading a surface and adding points from a file"
67             << "; merging the points and writing the surface to another file"
68             << nl << endl;
70         Info<< "Surface  : " << inFileName1<< nl
71             << "Points   : " << args.option("points") << nl
72             << "Writing  : " << outFileName << nl << endl;
73     }
74     else
75     {
76         Info<< "Reading two surfaces"
77             << "; merging points and writing the surface to another file"
78             << nl << endl;
80         if (mergeRegions)
81         {
82             Info<< "Regions from the two files will get merged" << nl
83                 << "Do not use this option if you want to keep the regions"
84                 << " separate" << nl << endl;
85         }
86         else
87         {
88             Info<< "Regions from the two files will not get merged" << nl
89                 << "Regions from " << inFileName2 << " will get offset so"
90                 << " as not to overlap with the regions in " << inFileName1
91                 << nl << endl;
92         }
95         Info<< "Surface1 : " << inFileName1<< nl
96             << "Surface2 : " << inFileName2<< nl
97             << "Writing  : " << outFileName << nl << endl;
98     }
100     const triSurface surface1(inFileName1);
102     Info<< "Surface1:" << endl;
103     surface1.writeStats(Info);
104     Info<< endl;
106     const pointField& points1 = surface1.points();
108     // Final surface
109     triSurface combinedSurf;
111     if (addPoint)
112     {
113         IFstream pointsFile(args.option("points"));
114         pointField extraPoints(pointsFile);
116         Info<< "Additional Points:" << extraPoints.size() << endl;
118         vectorField pointsAll(points1);
119         label pointI = pointsAll.size();
120         pointsAll.setSize(pointsAll.size() + extraPoints.size());
122         forAll(extraPoints, i)
123         {
124             pointsAll[pointI++] = extraPoints[i];
125         }
127         combinedSurf = triSurface(surface1, surface1.patches(), pointsAll);
128     }
129     else
130     {
131         const triSurface surface2(inFileName2);
133         Info<< "Surface2:" << endl;
134         surface2.writeStats(Info);
135         Info<< endl;
138         // Make new storage
139         List<labelledTri> facesAll(surface1.size() + surface2.size());
141         const pointField& points2 = surface2.points();
143         vectorField pointsAll(points1.size() + points2.size());
146         label pointi = 0;
147         // Copy points1 into pointsAll
148         forAll(points1, point1i)
149         {
150             pointsAll[pointi++] = points1[point1i];
151         }
152         // Add surface2 points
153         forAll(points2, point2i)
154         {
155             pointsAll[pointi++] = points2[point2i];
156         }
159         label trianglei = 0;
161         // Copy triangles1 into trianglesAll
162         forAll(surface1, faceI)
163         {
164             facesAll[trianglei++] = surface1[faceI];
165         }
166         label nRegions1 = surface1.patches().size();
169         if (!mergeRegions)
170         {
171             Info<< "Surface " << inFileName1 << " has " << nRegions1
172                 << " regions"
173                 << nl
174                 << "All region numbers in " << inFileName2 << " will be offset"
175                 << " by this amount" << nl << endl;
176         }
178         // Add (renumbered) surface2 triangles
179         forAll(surface2, faceI)
180         {
181             const labelledTri& tri = surface2[faceI];
183             labelledTri& destTri = facesAll[trianglei++];
184             destTri[0] = tri[0] + points1.size();
185             destTri[1] = tri[1] + points1.size();
186             destTri[2] = tri[2] + points1.size();
187             if (mergeRegions)
188             {
189                 destTri.region() = tri.region();
190             }
191             else
192             {
193                 destTri.region() = tri.region() + nRegions1;
194             }
195         }
197         label nRegions2 = surface2.patches().size();
199         geometricSurfacePatchList newPatches;
201         if (mergeRegions)
202         {
203             // Overwrite
204             newPatches.setSize(max(nRegions1, nRegions2));
206             forAll(surface1.patches(), patchI)
207             {
208                 newPatches[patchI] = surface1.patches()[patchI];
209             }
210             forAll(surface2.patches(), patchI)
211             {
212                 newPatches[patchI] = surface2.patches()[patchI];
213             }
214         }
215         else
216         {
217             Info<< "Regions from " << inFileName2 << " have been renumbered:"
218                 << nl
219                 << "    old\tnew" << nl;
221             for (label regionI = 0; regionI < nRegions2; regionI++)
222             {
223                 Info<< "    " << regionI << '\t' << regionI+nRegions1
224                     << nl;
225             }
226             Info<< nl;
228             newPatches.setSize(nRegions1 + nRegions2);
230             label newPatchI = 0;
232             forAll(surface1.patches(), patchI)
233             {
234                 newPatches[newPatchI++] = surface1.patches()[patchI];
235             }
237             forAll(surface2.patches(), patchI)
238             {
239                 newPatches[newPatchI++] = surface2.patches()[patchI];
240             }
241         }
244         Info<< "New patches:" << nl;
245         forAll(newPatches, patchI)
246         {
247             Info<< "    " << patchI << '\t' << newPatches[patchI].name() << nl;
248         }
249         Info<< endl;
252         // Construct new surface mesh
253         combinedSurf = triSurface(facesAll, newPatches, pointsAll);
254     }
256     // Merge all common points and do some checks
257     combinedSurf.cleanup(true);
259     Info<< "Merged surface:" << endl;
261     combinedSurf.writeStats(Info);
263     Info<< endl;
265     Info << "Writing : " << outFileName << endl;
267     // No need to 'group' while writing since all in correct order anyway.
268     combinedSurf.write(outFileName);
270     Info << "End\n" << endl;
272     return 0;
276 // ************************************************************************* //