Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
subdivider.cc
1 /* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openmesh.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenMesh. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 * ========================================================================= */
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $Date$ *
46 * *
47 \*===========================================================================*/
48
49 #include <iostream>
50 #include <sstream>
51 // ---------------------------------------- OpenMesh Stuff
52 #include <OpenMesh/Core/IO/MeshIO.hh>
53 #include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
54 #include <OpenMesh/Tools/Utils/Timer.hh>
55 #include <OpenMesh/Tools/Utils/getopt.h>
56 // ---------------------------------------- Subdivider
57 #include <OpenMesh/Tools/Subdivider/Uniform/Sqrt3T.hh>
58 #include <OpenMesh/Tools/Subdivider/Uniform/LoopT.hh>
59 #include <OpenMesh/Tools/Subdivider/Uniform/CompositeSqrt3T.hh>
60 #include <OpenMesh/Tools/Subdivider/Uniform/CompositeLoopT.hh>
61 #include <OpenMesh/Tools/Subdivider/Uniform/Sqrt3InterpolatingSubdividerLabsikGreinerT.hh>
62 #include <OpenMesh/Tools/Subdivider/Uniform/ModifiedButterFlyT.hh>
63 #include <OpenMesh/Tools/Subdivider/Uniform/CatmullClarkT.hh>
64
65 // ----------------------------------------------------------------------------
66
67 using namespace OpenMesh::Subdivider;
68
69 typedef OpenMesh::Subdivider::Uniform::CompositeTraits CTraits;
70 typedef OpenMesh::TriMesh_ArrayKernelT<CTraits> CMesh;
71
72 typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;
73 typedef Uniform::Sqrt3T< Mesh > Sqrt3;
74 typedef Uniform::LoopT< Mesh > Loop;
75 typedef Uniform::CompositeSqrt3T< CMesh > CompositeSqrt3;
76 typedef Uniform::CompositeLoopT< CMesh > CompositeLoop;
77 typedef Uniform::InterpolatingSqrt3LGT< Mesh > InterpolatingSqrt3LG;
78 typedef Uniform::ModifiedButterflyT< Mesh > ModifiedButterfly;
79 typedef Uniform::CatmullClarkT< Mesh > CatmullClark;
80
81 using OpenMesh::Utils::Timer;
82
83 // ----------------------------------------------------------------------------
84
85 std::map< std::string, double > timings;
86
87 // ----------------------------------------------------------------------------
88
89 template < typename Subdivider >
90 bool subdivide( typename Subdivider::mesh_t& _m, size_t _n,
91 Timer::Format _fmt )
92 {
93 bool rc;
94 Timer t;
95 Subdivider subdivide;
96
97 std::cout << "Subdivide " << _n
98 << " times with '" << subdivide.name() << "'\n";
99
100 subdivide.attach(_m);
101 t.start();
102 rc=subdivide( _n );
103 t.stop();
104 subdivide.detach();
105
106 if (rc)
107 {
108 std::cout << " Done [" << t.as_string(_fmt) << "]\n";
109 timings[subdivide.name()] = t.seconds();
110 }
111 else
112 std::cout << " Failed!\n";
113 return rc;
114 }
115
116 // ----------------------------------------------------------------------------
117
118 void usage_and_exit(int _xcode);
119
120 // ----------------------------------------------------------------------------
121
122 template < typename Subdivider >
123 int mainT( size_t _n,
124 const std::string& _ifname,
125 const std::string& _ofname,
126 const Timer::Format _fmt )
127 {
128 // -------------------- read mesh
129 std::cout << "Read mesh from file " << _ifname << std::endl;
130
131 typename Subdivider::mesh_t mesh;
132
133 if ( OpenMesh::IO::read_mesh( mesh, _ifname ) )
134 std::cout << " Ok\n";
135 else
136 {
137 std::cout << " Failed!\n";
138 return 1;
139 }
140
141 std::cout << " #V " << mesh.n_vertices()
142 << ", #F " << mesh.n_faces()
143 << ", #E " << mesh.n_edges() << std::endl;
144
145 // -------------------- subdividing
146 try
147 {
148 if (!subdivide< Subdivider >( mesh, _n, _fmt ))
149 return 1;
150 }
151 catch(std::bad_alloc& x)
152 {
153 std::cerr << "Out of memory: " << x.what() << std::endl;
154 return 1;
155 }
156 catch(std::exception& x)
157 {
158 std::cerr << x.what() << std::endl;
159 return 1;
160 }
161 catch(...)
162 {
163 std::cerr << "Unknown exception!\n";
164 return 1;
165 }
166
167 // -------------------- write mesh
168
169 std::cout << " #V " << mesh.n_vertices()
170 << ", #F " << mesh.n_faces()
171 << ", #E " << mesh.n_edges() << std::endl;
172
173 if ( !_ofname.empty() )
174 {
175 std::cout << "Write resulting mesh to file " << _ofname << "..";
176 if (OpenMesh::IO::write_mesh(mesh, _ofname, OpenMesh::IO::Options::Binary))
177 {
178 std::cout << "ok\n";
179 }
180 else
181 {
182 std::cerr << "Failed! Could not write file!\n";
183 return 1;
184 }
185 }
186
187 return 0;
188 }
189
190 // ----------------------------------------------------------------------------
191
192 int main(int argc, char **argv)
193 {
194 int c;
195
196 bool compare_all = false;
197 size_t n;
198 std::string ifname;
199 std::string ofname;
200
201 enum {
202 TypeSqrt3,
203 TypeLoop,
204 TypeCompSqrt3,
205 TypeCompLoop,
206 TypeLabsikGreiner,
207 TypeModButterfly,
208 TypeCatmullClark
209 } st = TypeSqrt3;
210
211 Timer::Format fmt = Timer::Automatic;
212
213 while ( (c=getopt(argc, argv, "csSlLbBhf:"))!=-1 )
214 {
215 switch(c)
216 {
217 case 'c': compare_all=true; break;
218 case 's': st = TypeSqrt3; break;
219 case 'S': st = TypeCompSqrt3; break;
220 case 'l': st = TypeLoop; break;
221 case 'L': st = TypeCompLoop; break;
222 case 'b': st = TypeLabsikGreiner; break;
223 case 'B': st = TypeModButterfly; break;
224 case 'C': st = TypeCatmullClark; std::cerr << "Not yet supported, as it needs a poly mesh!"; break;
225 case 'f':
226 {
227 switch(*optarg)
228 {
229 case 'm': fmt = Timer::MSeconds; break;
230 case 'c': fmt = Timer::HSeconds; break;
231 case 's': fmt = Timer::Seconds; break;
232 case 'a':
233 default: fmt = Timer::Automatic; break;
234 }
235 break;
236 }
237 case 'h': usage_and_exit(0);
238 case '?':
239 default: usage_and_exit(1);
240 }
241 }
242
243 if (argc-optind < 2)
244 usage_and_exit(1);
245
246 // # iterations
247 {
248 std::stringstream str; str << argv[optind]; str >> n;
249 }
250
251 // input file
252 ifname = argv[++optind];
253
254 // output file, if provided
255 if ( ++optind < argc )
256 ofname = argv[optind];
257
258
259 // --------------------
260 if ( compare_all )
261 {
262 int rc;
263 rc = mainT<Sqrt3> ( n, ifname, "", fmt );
264 rc += mainT<Loop> ( n, ifname, "", fmt );
265 rc += mainT<CompositeSqrt3> ( n, ifname, "", fmt );
266 rc += mainT<CompositeLoop> ( n, ifname, "", fmt );
267 rc += mainT<InterpolatingSqrt3LG> ( n, ifname, "", fmt );
268 rc += mainT<ModifiedButterfly> ( n, ifname, "", fmt );
269 rc += mainT<CatmullClark> ( n, ifname, "", fmt );
270
271 if (rc)
272 return rc;
273
274 std::cout << std::endl;
275
276 std::map< std::string, double >::iterator it;
277
278 std::cout << "Timings:\n";
279 for(it = timings.begin();it!=timings.end();++it)
280 std::cout << it->first << ": " << Timer::as_string(it->second)
281 << std::endl;
282 std::cout << std::endl;
283 std::cout << "Ratio composite/native algorithm:\n";
284 std::cout << "sqrt(3): "
285 << timings["Uniform Composite Sqrt3"]/timings["Uniform Sqrt3"]
286 << std::endl
287 << "loop : "
288 << timings["Uniform Composite Loop"]/timings["Uniform Loop"]
289 << std::endl
290 << "Interpolating sqrt(3) : "
291 << timings["Uniform Interpolating Sqrt3"]/timings["Uniform Sqrt3"]
292 << std::endl;
293 return 0;
294 }
295 else switch(st)
296 {
297 case TypeSqrt3:
298 return mainT<Sqrt3>( n, ifname, ofname, fmt );
299 case TypeLoop:
300 return mainT<Loop>( n, ifname, ofname, fmt );
301 case TypeCompSqrt3:
302 return mainT<CompositeSqrt3>( n, ifname, ofname, fmt );
303 case TypeCompLoop:
304 return mainT<CompositeLoop> ( n, ifname, ofname, fmt );
305 case TypeLabsikGreiner:
306 return mainT<InterpolatingSqrt3LG> ( n, ifname, ofname, fmt );
307 case TypeModButterfly:
308 return mainT<ModifiedButterfly> ( n, ifname, ofname, fmt );
309 case TypeCatmullClark:
310 return mainT<CatmullClark> ( n, ifname, ofname, fmt );
311 }
312 return 1;
313 }
314
315 // ----------------------------------------------------------------------------
316
317 void usage_and_exit(int _xcode)
318 {
319 std::cout << "Usage: subdivide [Subdivider Type] #Iterations Input [Output].\n";
320 std::cout << std::endl;
321 std::cout << "Subdivider Type\n"
322 << std::endl
323 << " -l\tLoop\n"
324 << " -L\tComposite Loop\n"
325 << " -s\tSqrt3\n"
326 << " -S\tComposite Sqrt3\n"
327 << " -b\tInterpolating Sqrt3 Labsik-Greiner\n"
328 << " -B\tModified Butterfly\n"
329 // << " -C\tCatmullClark\n"
330 << std::endl;
331 exit(_xcode);
332 }
OpenMesh::Subdivider::Uniform::Sqrt3T
Definition: Sqrt3T.hh:103
OpenMesh::IO::read_mesh
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:104
OpenMesh::Utils::Timer::stop
void stop(void)
Stop measurement.
OpenMesh::Subdivider::Uniform::CompositeTraits
Definition: CompositeTraits.hh:84
Sqrt3InterpolatingSubdividerLabsikGreinerT.hh
OpenMesh::Subdivider::Uniform::ModifiedButterflyT
Definition: ModifiedButterFlyT.hh:99
OpenMesh::TriMesh_ArrayKernelT
Definition: TriMesh_ArrayKernelT.hh:98
OpenMesh::Subdivider::Uniform::LoopT
Definition: LoopT.hh:96
OpenMesh::Utils::Timer::as_string
std::string as_string(Format format=Automatic)
OpenMesh::Subdivider::Uniform::CompositeSqrt3T
Definition: CompositeSqrt3T.hh:81
CompositeSqrt3T.hh
OpenMesh::Subdivider::Uniform::CatmullClarkT
Definition: CatmullClarkT.hh:92
ModifiedButterFlyT.hh
Timer.hh
OpenMesh::Subdivider
OpenMesh::Subdivider::Uniform::CompositeLoopT
Definition: CompositeLoopT.hh:81
OpenMesh::Utils::Timer::start
void start(void)
Start measurement.
OpenMesh::IO::Options::Binary
Set binary mode for r/w.
Definition: Options.hh:105
OpenMesh::Utils::Timer::seconds
double seconds(void) const
Returns measured time in seconds, if the timer is in state 'Stopped'.
CompositeLoopT.hh
OpenMesh::Subdivider::Uniform::InterpolatingSqrt3LGT
Definition: Sqrt3InterpolatingSubdividerLabsikGreinerT.hh:113
OpenMesh::IO::write_mesh
bool write_mesh(const Mesh &_mesh, const std::string &_filename, Options _opt=Options::Default, std::streamsize _precision=6)
Write a mesh to the file _filename.
Definition: MeshIO.hh:199
LoopT.hh
OpenMesh::Utils::Timer
Definition: Timer.hh:87
Sqrt3T.hh
CatmullClarkT.hh