surfaceCoarsen.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) 2011-2015 OpenFOAM Foundation
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  surfaceCoarsen
26 
27 Description
28  Surface coarsening using `bunnylod'
29 
30  Reference:
31  \verbatim
32  Polygon Reduction Demo
33  By Stan Melax (c) 1998
34  mailto:melax@cs.ualberta.ca
35  http://www.cs.ualberta.ca/~melax
36  \endverbatim
37 
38 \*---------------------------------------------------------------------------*/
39 
40 #include "argList.H"
41 #include "fileName.H"
42 #include "triSurface.H"
43 #include "OFstream.H"
44 #include "triFace.H"
45 #include "triFaceList.H"
46 
47 // From bunnylod
48 #include "progmesh.h"
49 
50 using namespace Foam;
51 
52 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
53 
54 int mapVertex(::List<int>& collapse_map, int a, int mx)
55 {
56  if (mx <= 0)
57  {
58  return 0;
59  }
60  while (a >= mx)
61  {
62  a = collapse_map[a];
63  }
64  return a;
65 }
66 
67 
68 
69 int main(int argc, char *argv[])
70 {
72  argList::validArgs.append("surfaceFile");
73  argList::validArgs.append("reductionFactor");
74  argList::validArgs.append("output surfaceFile");
75  argList args(argc, argv);
76 
77  const fileName inFileName = args[1];
78  const scalar reduction = args.argRead<scalar>(2);
79  const fileName outFileName = args[3];
80 
81  if (reduction <= 0 || reduction > 1)
82  {
84  << "Reduction factor " << reduction
85  << " should be within 0..1" << endl
86  << "(it is the reduction in number of vertices)"
87  << exit(FatalError);
88  }
89 
90  Info<< "Input surface :" << inFileName << endl
91  << "Reduction factor:" << reduction << endl
92  << "Output surface :" << outFileName << endl << endl;
93 
94  const triSurface surf(inFileName);
95 
96  Info<< "Surface:" << endl;
97  surf.writeStats(Info);
98  Info<< endl;
99 
100 
101  ::List< ::Vector> vert; // global list of vertices
102  ::List< ::tridata> tri; // global list of triangles
103 
104 
105  // Convert triSurface to progmesh format. Note: can use global point
106  // numbering since surface read in from file.
107  const pointField& pts = surf.points();
108 
109  forAll(pts, ptI)
110  {
111  const point& pt = pts[ptI];
112 
113  vert.Add( ::Vector(pt.x(), pt.y(), pt.z()));
114  }
115 
116  forAll(surf, faceI)
117  {
118  const labelledTri& f = surf[faceI];
119 
120  tridata td;
121  td.v[0]=f[0];
122  td.v[1]=f[1];
123  td.v[2]=f[2];
124  tri.Add(td);
125  }
126 
127  ::List<int> collapse_map; // to which neighbor each vertex collapses
128  ::List<int> permutation;
129 
130  ::ProgressiveMesh(vert,tri,collapse_map,permutation);
131 
132  // rearrange the vertex list
133  ::List< ::Vector> temp_list;
134  for (int i=0;i<vert.num;i++)
135  {
136  temp_list.Add(vert[i]);
137  }
138  for (int i=0;i<vert.num;i++)
139  {
140  vert[permutation[i]]=temp_list[i];
141  }
142 
143  // update the changes in the entries in the triangle list
144  for (int i=0;i<tri.num;i++)
145  {
146  for (int j=0;j<3;j++)
147  {
148  tri[i].v[j] = permutation[tri[i].v[j]];
149  }
150  }
151 
152  // Only get triangles with non-collapsed edges.
153  int render_num = int(reduction * surf.nPoints());
154 
155  Info<< "Reducing to " << render_num << " vertices" << endl;
156 
157 
158  // Storage for new surface.
159  Foam::List<labelledTri> newTris(surf.size());
160 
161  label newI = 0;
162 
163  for (int i=0; i<tri.num; i++)
164  {
165  int p0 = mapVertex(collapse_map, tri[i].v[0], render_num);
166  int p1 = mapVertex(collapse_map, tri[i].v[1], render_num);
167  int p2 = mapVertex(collapse_map, tri[i].v[2], render_num);
168 
169  // note: serious optimization opportunity here,
170  // by sorting the triangles the following "continue"
171  // could have been made into a "break" statement.
172  if (p0 == p1 || p1 == p2 || p2 == p0)
173  {
174  continue;
175  }
176 
177  newTris[newI++] = labelledTri(p0, p1, p2, 0);
178  }
179  newTris.setSize(newI);
180 
181  // Convert vert into pointField.
182  pointField newPoints(vert.num);
183 
184  for (int i=0; i<vert.num; i++)
185  {
186  const ::Vector & v = vert[i];
187 
188  newPoints[i] = point(v.x, v.y, v.z);
189  }
190 
191  triSurface surf2(newTris, newPoints);
192 
193  triSurface outSurf
194  (
195  surf2.localFaces(),
196  surf2.patches(),
197  surf2.localPoints()
198  );
199 
200  Info<< "Coarsened surface:" << endl;
201  surf2.writeStats(Info);
202  Info<< endl;
203 
204  Info<< "Writing to file " << outFileName << endl << endl;
205 
206  surf2.write(outFileName);
207 
208  Info<< "End\n" << endl;
209 
210  return 0;
211 }
212 
213 
214 // ************************************************************************* //
Foam::argList::validArgs
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:143
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::argList
Extract command arguments and options from the supplied argc and argv parameters.
Definition: argList.H:97
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
triFace.H
OFstream.H
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:57
Foam::Ostream::write
virtual Ostream & write(const token &)=0
Write next token to stream.
Foam::Info
messageStream Info
argList.H
fileName.H
main
int main(int argc, char *argv[])
Definition: postCalc.C:54
Foam::Vector::x
const Cmpt & x() const
Definition: VectorI.H:65
Foam::FatalError
error FatalError
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::Vector::z
const Cmpt & z() const
Definition: VectorI.H:77
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::List< int >
Foam::labelledTri
Triangle with additional region number.
Definition: labelledTri.H:49
Foam::argList::argRead
T argRead(const label index) const
Read a value from the argument at index.
Definition: argListI.H:177
Foam::Vector::y
const Cmpt & y() const
Definition: VectorI.H:71
Foam::point
vector point
Point is a vector.
Definition: point.H:41
triFaceList.H
Foam::argList::noParallel
static void noParallel()
Remove the parallel options.
Definition: argList.C:161
args
Foam::argList args(argc, argv)