1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 Surface coarsening using 'bunnylod':
28 Polygon Reduction Demo
29 By Stan Melax (c) 1998
30 mailto:melax@cs.ualberta.ca
31 http://www.cs.ualberta.ca/~melax
34 \*---------------------------------------------------------------------------*/
38 #include "triSurface.H"
41 #include "triFaceList.H"
48 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
50 int mapVertex(::List<int>& collapse_map, int a, int mx)
66 int main(int argc, char *argv[])
68 argList::noParallel();
69 argList::validArgs.clear();
70 argList::validArgs.append("Foam surface file");
71 argList::validArgs.append("reduction factor");
72 argList::validArgs.append("Foam output file");
73 argList args(argc, argv);
75 fileName inFileName(args.additionalArgs()[0]);
77 scalar reduction(readScalar(IStringStream(args.additionalArgs()[1])()));
79 if (reduction <= 0 || reduction > 1)
81 FatalErrorIn(args.executable())
82 << "Reduction factor " << reduction
83 << " should be within 0..1" << endl
84 << "(it is the reduction in number of vertices)"
88 fileName outFileName(args.additionalArgs()[2]);
90 Info<< "Input surface :" << inFileName << endl
91 << "Reduction factor:" << reduction << endl
92 << "Output surface :" << outFileName << endl << endl;
94 const triSurface surf(inFileName);
96 Info<< "Surface:" << endl;
97 surf.writeStats(Info);
101 ::List< ::Vector> vert; // global list of vertices
102 ::List< ::tridata> tri; // global list of triangles
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();
111 const point& pt = pts[ptI];
113 vert.Add( ::Vector(pt.x(), pt.y(), pt.z()));
118 const labelledTri& f = surf[faceI];
127 ::List<int> collapse_map; // to which neighbor each vertex collapses
128 ::List<int> permutation;
130 ::ProgressiveMesh(vert,tri,collapse_map,permutation);
132 // rearrange the vertex list
133 ::List< ::Vector> temp_list;
134 for(int i=0;i<vert.num;i++)
136 temp_list.Add(vert[i]);
138 for(int i=0;i<vert.num;i++)
140 vert[permutation[i]]=temp_list[i];
143 // update the changes in the entries in the triangle list
144 for(int i=0;i<tri.num;i++)
148 tri[i].v[j] = permutation[tri[i].v[j]];
152 // Only get triangles with non-collapsed edges.
153 int render_num = int(reduction * surf.nPoints());
155 Info<< "Reducing to " << render_num << " vertices" << endl;
158 // Storage for new surface.
159 Foam::List<labelledTri> newTris(surf.size());
163 for (int i=0; i<tri.num; i++)
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);
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)
177 newTris[newI++] = labelledTri(p0, p1, p2, 0);
179 newTris.setSize(newI);
181 // Convert vert into pointField.
182 pointField newPoints(vert.num);
184 for(int i=0; i<vert.num; i++)
186 const ::Vector & v = vert[i];
188 newPoints[i] = point(v.x, v.y, v.z);
191 triSurface surf2(newTris, newPoints);
200 Info<< "Coarsened surface:" << endl;
201 surf2.writeStats(Info);
204 Info<< "Writing to file " << outFileName << endl << endl;
206 surf2.write(outFileName);
208 Info << "End\n" << endl;
214 // ************************************************************************* //