MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2010 Sandia National Laboratories. Developed at the 00005 University of Wisconsin--Madison under SNL contract number 00006 624796. The U.S. Government and the University of Wisconsin 00007 retain certain rights to this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2010) [email protected] 00024 00025 ***************************************************************** */ 00026 00027 /** \file untangle.cpp 00028 * \brief tast untangle wrapper 00029 * \author Jason Kraftcheck 00030 */ 00031 #include "TestUtil.hpp" 00032 00033 #include "MeshImpl.hpp" 00034 #include "MsqError.hpp" 00035 #include "MsqVertex.hpp" 00036 #include "PlanarDomain.hpp" 00037 #include "UntangleWrapper.hpp" 00038 #include "QualityAssessor.hpp" 00039 00040 #include <iostream> 00041 using std::cout; 00042 using std::endl; 00043 #include <cstdlib> 00044 00045 using namespace MBMesquite; 00046 00047 std::string VTK_2D_DIR = TestDir + "unittest/mesquite/2D/vtk/"; 00048 00049 // Test untangle wrapper 00050 // Assumes all meshes lie in a plane for which the normal is [0,0,1]. 00051 int uwt( bool skip, 00052 UntangleWrapper::UntangleMetric metric, 00053 const char* input_file, 00054 int expected_number_of_remaining_inverted_elems, 00055 bool flip_domain = false ); 00056 00057 bool brief_output = false; 00058 bool write_output = false; 00059 double mu_sigma = -1; 00060 double beta = -1; 00061 00062 void usage( const char* argv0 ) 00063 { 00064 std::cerr << "Usage: " << argv0 << " [-<flags>] [-c <sigma>] [-b <beta>]" << std::endl 00065 << " " << argv0 << " -h" << std::endl; 00066 } 00067 void help( const char* argv0 ) 00068 { 00069 std::cout << "Usage: " << argv0 << " [-<flags>] [-c <sigma>] [-b <beta>]" << std::endl 00070 << "Flags: -q : brief output" << std::endl 00071 << " -w : write result meshes" << std::endl 00072 << " -B : skip tests using untangle beta target metric" << std::endl 00073 << " -Z : skip tests using size untangle target metric" << std::endl 00074 << " -P : skip tests using shapesize untangle target metric" << std::endl 00075 << " -H : skip tests using 'tangled_horse1.vtk' as input" << std::endl 00076 << " -Q : skip tests using 'hole_in_square_tanglap.vtk' as input" << std::endl 00077 << " -I : skip tests using 'inverted-hole-2.vtk' as input" << std::endl 00078 << " -S : skip tests using 'shest_grid32.vtk' as input" << std::endl 00079 << " -c : specify sigma value for untangle metrics" << std::endl 00080 << " -b : specify beta value for untangle beta metric" << std::endl 00081 << std::endl; 00082 } 00083 00084 int main( int argc, char* argv[] ) 00085 { 00086 bool skip_beta = false; 00087 bool skip_size = false; 00088 bool skip_shape = false; 00089 bool skip_horse = false; 00090 bool skip_hole = false; 00091 bool skip_invrt = false; 00092 bool skip_shest = false; 00093 std::list< double* > expected; 00094 00095 for( int i = 1; i < argc; ++i ) 00096 { 00097 if( !expected.empty() ) 00098 { 00099 char* endptr; 00100 *expected.front() = strtod( argv[i], &endptr ); 00101 if( *endptr || *expected.front() <= 0 ) 00102 { 00103 std::cerr << "Expected positive number, found \"" << argv[i] << '"' << std::endl; 00104 usage( argv[0] ); 00105 return 1; 00106 } 00107 expected.pop_front(); 00108 } 00109 else if( argv[i][0] == '-' && argv[i][1] ) 00110 { 00111 for( int j = 1; argv[i][j]; ++j ) 00112 { 00113 switch( argv[i][j] ) 00114 { 00115 case 'q': 00116 brief_output = true; 00117 break; 00118 case 'w': 00119 write_output = true; 00120 break; 00121 case 'B': 00122 skip_beta = true; 00123 break; 00124 case 'Z': 00125 skip_size = true; 00126 break; 00127 case 'P': 00128 skip_shape = true; 00129 break; 00130 case 'H': 00131 skip_horse = true; 00132 break; 00133 case 'Q': 00134 skip_hole = true; 00135 break; 00136 case 'I': 00137 skip_invrt = true; 00138 break; 00139 case 'S': 00140 skip_shest = true; 00141 break; 00142 case 'c': 00143 expected.push_back( &mu_sigma ); 00144 break; 00145 case 'b': 00146 expected.push_back( &beta ); 00147 break; 00148 case 'h': 00149 help( argv[0] ); 00150 return 0; 00151 default: 00152 std::cerr << "Invalid flag: -" << argv[i][j] << std::endl; 00153 usage( argv[0] ); 00154 return 1; 00155 } 00156 } 00157 } 00158 else 00159 { 00160 std::cerr << "Unexpected argument: \"" << argv[i] << '"' << std::endl; 00161 usage( argv[0] ); 00162 return 1; 00163 } 00164 } 00165 00166 int result = 0; 00167 00168 result += uwt( skip_beta || skip_horse, UntangleWrapper::BETA, "quads/tangled/tangled_horse1.vtk", 0 ); 00169 result += uwt( skip_beta || skip_hole, UntangleWrapper::BETA, "quads/tangled/hole_in_square_tanglap.vtk", 0, true ); 00170 result += uwt( skip_beta || skip_invrt, UntangleWrapper::BETA, "quads/tangled/inverted-hole-2.vtk", 0 ); 00171 result += uwt( skip_beta || skip_shest, UntangleWrapper::BETA, "quads/untangled/shest_grid32.vtk", 0 ); 00172 00173 result += uwt( skip_size || skip_horse, UntangleWrapper::SIZE, "quads/tangled/tangled_horse1.vtk", 0 ); 00174 result += uwt( skip_size || skip_hole, UntangleWrapper::SIZE, "quads/tangled/hole_in_square_tanglap.vtk", 6, true ); 00175 result += uwt( skip_size || skip_invrt, UntangleWrapper::SIZE, "quads/tangled/inverted-hole-2.vtk", 0 ); 00176 result += uwt( skip_size || skip_shest, UntangleWrapper::SIZE, "quads/untangled/shest_grid32.vtk", 0 ); 00177 00178 result += uwt( skip_shape || skip_horse, UntangleWrapper::SHAPESIZE, "quads/tangled/tangled_horse1.vtk", 0 ); 00179 result += 00180 uwt( skip_shape || skip_hole, UntangleWrapper::SHAPESIZE, "quads/tangled/hole_in_square_tanglap.vtk", 0, true ); 00181 result += uwt( skip_shape || skip_invrt, UntangleWrapper::SHAPESIZE, "quads/tangled/inverted-hole-2.vtk", 8 ); 00182 result += uwt( skip_shape || skip_shest, UntangleWrapper::SHAPESIZE, "quads/untangled/shest_grid32.vtk", 0 ); 00183 00184 return result; 00185 } 00186 00187 const char* tostr( UntangleWrapper::UntangleMetric m ) 00188 { 00189 static const char BETA[] = "BETA"; 00190 static const char SIZE[] = "SIZE"; 00191 static const char SHAPESIZE[] = "SHAPESIZE"; 00192 switch( m ) 00193 { 00194 case UntangleWrapper::BETA: 00195 return BETA; 00196 case UntangleWrapper::SIZE: 00197 return SIZE; 00198 case UntangleWrapper::SHAPESIZE: 00199 return SHAPESIZE; 00200 } 00201 return 0; 00202 } 00203 00204 int uwt( bool skip, 00205 UntangleWrapper::UntangleMetric metric, 00206 const char* input_file_base, 00207 int expected, 00208 bool flip_domain ) 00209 { 00210 if( skip ) return 0; 00211 00212 if( !brief_output ) std::cout << std::endl << "**********************************************" << std::endl; 00213 std::cout << "Running \"" << input_file_base << "\" for " << tostr( metric ) << std::endl; 00214 if( !brief_output ) std::cout << "**********************************************" << std::endl << std::endl; 00215 00216 // get mesh 00217 MsqError err; 00218 MeshImpl mesh; 00219 std::string input_file( VTK_2D_DIR ); 00220 input_file += input_file_base; 00221 mesh.read_vtk( input_file.c_str(), err ); 00222 if( err ) 00223 { 00224 std::cerr << err << std::endl; 00225 std::cerr << "ERROR: " << input_file << " : failed to read file" << std::endl; 00226 return 1; 00227 } 00228 // get domain 00229 std::vector< Mesh::VertexHandle > verts; 00230 mesh.get_all_vertices( verts, err ); 00231 if( err || verts.empty() ) abort(); 00232 MsqVertex coords; 00233 mesh.vertices_get_coordinates( arrptr( verts ), &coords, 1, err ); 00234 if( err ) abort(); 00235 Vector3D norm( 0, 0, flip_domain ? -1 : 1 ); 00236 PlanarDomain domain( norm, coords ); 00237 // run wrapper 00238 UntangleWrapper wrapper( metric ); 00239 wrapper.set_vertex_movement_limit_factor( 0.005 ); 00240 double constant = ( metric == UntangleWrapper::BETA ) ? beta : mu_sigma; 00241 if( constant > 0 ) wrapper.set_metric_constant( constant ); 00242 if( brief_output ) wrapper.quality_assessor().disable_printing_results(); 00243 MeshDomainAssoc mesh_and_domain = MeshDomainAssoc( &mesh, &domain ); 00244 wrapper.run_instructions( &mesh_and_domain, err ); 00245 if( err ) 00246 { 00247 std::cerr << err << std::endl; 00248 std::cerr << "ERROR: optimization failed" << std::endl; 00249 return 1; 00250 } 00251 // write output file 00252 if( write_output ) 00253 { 00254 std::string result_file( tostr( metric ) ); 00255 result_file += "-"; 00256 result_file += input_file_base; 00257 mesh.write_vtk( result_file.c_str(), err ); 00258 if( err ) 00259 { 00260 std::cerr << err << std::endl; 00261 std::cerr << "ERROR: " << result_file << " : failed to write file" << std::endl; 00262 err.clear(); 00263 } 00264 else 00265 { 00266 std::cerr << "Wrote file: " << result_file << std::endl; 00267 } 00268 } 00269 00270 // test number of inverted elements 00271 int count, junk; 00272 wrapper.quality_assessor().get_inverted_element_count( count, junk, err ); 00273 if( err ) abort(); 00274 if( count < expected ) 00275 { 00276 std::cout << "WARNING: expected " << expected << " inverted elements but finished with only " << count 00277 << std::endl 00278 << "Test needs to be updated?" << std::endl 00279 << std::endl; 00280 return 0; 00281 } 00282 else if( count == expected ) 00283 { 00284 std::cout << "Completed with " << count << " inverted elements remaining" << std::endl << std::endl; 00285 return 0; 00286 } 00287 else 00288 { 00289 std::cerr << "ERROR: expected " << expected << " inverted elements but finished with " << count << std::endl 00290 << std::endl; 00291 return 1; 00292 } 00293 }