53int main(
int argc,
char *argv[])
57 "Add two surfaces via a geometric merge on points."
58 " Does not check for overlapping/intersecting triangles."
70 "Provide additional points"
75 "Combine regions from both surfaces"
81 "Geometry scaling factor on input surfaces"
91 const int optVerbose =
args.verbose();
92 const bool addPoint =
args.found(
"points");
93 const bool mergeRegions =
args.found(
"mergeRegions");
95 const scalar scaleFactor =
args.getOrDefault<scalar>(
"scale", -1);
99 Info<<
"Reading a surface and adding points from a file"
100 <<
"; merging the points and writing the surface to another file"
103 Info<<
"Surface : " << inFileName1<<
nl
105 <<
"Writing : " << outFileName <<
nl <<
endl;
109 Info<<
"Reading two surfaces"
110 <<
"; merging points and writing the surface to another file"
115 Info<<
"Regions from the two files will get merged" <<
nl
116 <<
"Do not use this option if you want to keep the regions"
117 <<
" separate" <<
nl <<
endl;
121 Info<<
"Regions from the two files will not get merged" <<
nl
122 <<
"Regions from " << inFileName2 <<
" will get offset so"
123 <<
" as not to overlap with the regions in " << inFileName1
128 Info<<
"Surface1 : " << inFileName1<<
nl
129 <<
"Surface2 : " << inFileName2<<
nl
130 <<
"Writing : " << outFileName <<
nl <<
endl;
135 Info<<
"Scaling : " << scaleFactor <<
nl;
138 const triSurface surface1(inFileName1, scaleFactor);
140 surface1.writeStats(
Info);
143 const pointField& points1 = surface1.points();
153 Info<<
"Additional Points:" << extraPoints.size() <<
endl;
156 label pointi = pointsAll.size();
157 pointsAll.setSize(pointsAll.size() + extraPoints.size());
159 for (
const auto& pt : extraPoints)
161 pointsAll[pointi++] = pt;
164 combinedSurf =
triSurface(surface1, surface1.patches(), pointsAll);
168 const triSurface surface2(inFileName2, scaleFactor);
170 surface2.writeStats(
Info);
175 List<labelledTri> facesAll(surface1.size() + surface2.size());
177 const pointField& points2 = surface2.points();
184 for (
const auto& pt : points1)
186 pointsAll[pointi++] = pt;
189 for (
const auto& pt : points2)
191 pointsAll[pointi++] = pt;
198 label nNewPatches = 0;
199 labelList patch1Map(surface1.patches().size());
200 labelList patch2Map(surface2.patches().size());
206 forAll(surface1.patches(), i)
208 const word&
name = surface1.patches()[i].name();
211 const label combinedi = nameToPatch(
name, nameToPatch.
size());
213 patch1Map[i] = combinedi;
218 forAll(surface2.patches(), i)
220 const word&
name = surface2.patches()[i].name();
223 const label combinedi = nameToPatch(
name, nameToPatch.
size());
225 patch2Map[i] = combinedi;
228 nNewPatches = nameToPatch.
size();
232 Info<<
"Surface " << inFileName1
233 <<
" has " << surface1.patches().size()
236 <<
"All region numbers in " << inFileName2 <<
" will be offset"
237 <<
" by this amount" <<
nl <<
endl;
239 patch1Map =
identity(surface1.patches().size());
240 patch2Map =
identity(surface2.patches().size(), patch1Map.size());
242 nNewPatches = surface1.patches().size()+surface2.patches().size();
251 destTri.triFace::operator=(tri);
252 destTri.
region() = patch1Map[tri.region()];
259 destTri[0] = tri[0] + points1.
size();
260 destTri[1] = tri[1] + points1.
size();
261 destTri[2] = tri[2] + points1.
size();
262 destTri.
region() = patch2Map[tri.region()];
267 forAll(surface1.patches(), patchi)
269 newPatches[patch1Map[patchi]] = surface1.patches()[patchi];
271 forAll(surface2.patches(), patchi)
273 newPatches[patch2Map[patchi]] = surface2.patches()[patchi];
276 Info<<
"New patches:" <<
nl;
277 forAll(newPatches, patchi)
279 Info<<
" " << patchi <<
'\t' << newPatches[patchi].name() <<
nl;
285 combinedSurf =
triSurface(facesAll, newPatches, pointsAll);
289 combinedSurf.
cleanup(optVerbose);
297 Info<<
"Writing : " << outFileName <<
endl;
300 combinedSurf.
write(outFileName, mergeRegions);
static constexpr label size() noexcept
Return the number of elements in the FixedList.
A HashTable similar to std::unordered_map.
label size() const noexcept
The number of elements in table.
Input from file stream as an ISstream, normally using std::ifstream for the actual input.
void size(const label n)
Older name for setAddressableSize.
Extract command arguments and options from the supplied argc and argv parameters.
static void addVerboseOption(const string &usage="", bool advanced=false)
Enable a 'verbose' bool option, with usage information.
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
static void noParallel()
Remove the parallel options.
static void addOption(const word &optName, const string ¶m="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
static void addNote(const string ¬e)
Add extra notes for the usage information.
A class for handling file names.
A triFace with additional (region) index.
label region() const noexcept
Return the region index.
Triangulated surface description with patch information.
void cleanup(const bool verbose)
Remove non-valid triangles.
void write(Ostream &os) const
Write to Ostream in simple OpenFOAM format.
void writeStats(Ostream &os) const
Write some statistics.
A class for handling words, derived from Foam::string.
List< label > labelList
A List of labels.
messageStream Info
Information stream (stdout output on master, null elsewhere).
Ostream & endl(Ostream &os)
Add newline and flush stream.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Field< vector > vectorField
Specialisation of Field<T> for vector.
List< geometricSurfacePatch > geometricSurfacePatchList
List of geometricSurfacePatch.
vectorField pointField
pointField is a vectorField.
constexpr char nl
The newline '\n' character (0x0a).
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.