int main(int argc, char* argv[]) { Mesquite::MsqPrintError err(cout); Mesquite::MeshImpl mesh; //mesh->read_exodus("transformed_mesh.exo", err); mesh.read_vtk(MESH_FILES_DIR "2D/vtk/quads/untangled/tfi_horse10x4-12.vtk", err); if (err) return 1; // Get all vertex coordinates from mesh std::vector<Mesquite::Mesh::VertexHandle> handles; mesh.get_all_vertices( handles, err ); if (err) return 1; if (handles.empty()) { std::cerr << "No verticies in mesh" << endl; return 1; } std::vector<Mesquite::MsqVertex> coords( handles.size() ); mesh.vertices_get_coordinates( arrptr(handles), arrptr(coords), handles.size(), err ); if (err) return 1; //create the matrix for affine transformation double array_entries[9]; array_entries[0]=0; array_entries[1]=1; array_entries[2]=0; array_entries[3]=1; array_entries[4]=0; array_entries[5]=0; array_entries[6]=0; array_entries[7]=0; array_entries[8]=1; //create the translation vector Matrix3D my_mat(array_entries); Vector3D my_vec(0, 0 , 10); MeshTransform my_transform(my_mat, my_vec); //mesh->write_exodus("original_mesh.exo", err); MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, 0); my_transform.loop_over_mesh(&mesh_and_domain, 0, err); if (err) return 1; //mesh->write_exodus("transformed_mesh.exo", err); mesh.write_vtk("transformed_mesh.vtk", err); if (err) return 1; // Get transformed coordinates std::vector<Mesquite::MsqVertex> coords2( handles.size() ); mesh.vertices_get_coordinates( arrptr(handles), arrptr(coords2), handles.size(), err ); if (err) return 1; // Compare vertex coordinates size_t invalid = 0; std::vector<Mesquite::MsqVertex>::iterator iter, iter2; iter = coords.begin(); iter2 = coords2.begin(); for ( ; iter != coords.end(); ++iter, ++iter2 ) { Mesquite::Vector3D xform = my_mat * *iter + my_vec; double d = (xform - *iter2).length(); if (d > EPSILON) ++invalid; } std::cerr << invalid << " vertices not within " << EPSILON << " of expected location" << std::endl; return (invalid != 0); }
int main(int argc, char* argv[]) { std::cout << std::endl << "********* Wrappers Timing Tests **********" << std::endl << "Version " << version_string(true) << std::endl << std::endl; Mesquite::MsqPrintError err(cout); Mesquite::MeshImpl mesh; // #################### Begin ShapeImprover tests ################### ShapeImprover si_wrapper; mesh.read_vtk(shape_improv_file_name_1, err); Timer t; si_wrapper.run_instructions(&mesh, err); if (err) return 1; double si_s_secs = t.since_birth(); std::cout << std::endl << "ShapeImprover small file optimization completed in " << si_s_secs << " seconds" << std::endl; mesh.clear(); mesh.read_vtk(shape_improv_file_name_2, err); t.reset(); si_wrapper.run_instructions(&mesh, err); if (err) return 1; double si_l_secs = t.since_birth(); std::cout << std::endl << "ShapeImprover large file optimization completed in " << si_l_secs << " seconds" << std::endl; // #################### Begin LaplacianWrapper tests ################### Vector3D pnt1(0,0,5); Vector3D s_norm(0,0,1); Mesquite::PlanarDomain msq_geom(s_norm, pnt1); LaplaceWrapper lp_wrapper; mesh.clear(); mesh.read_vtk(laplacian_file_name_1, err); if (err) return 1; MeshDomainAssoc mesh_and_domain4 = MeshDomainAssoc(&mesh, &msq_geom); t.reset(); lp_wrapper.run_instructions(&mesh_and_domain4, err); if (err) return 1; double lp_s_secs = t.since_birth(); std::cout << std::endl << "LaplacianWrapper small file optimization completed in " << lp_s_secs << " seconds" << std::endl; Vector3D pnt2(0,0,0); Mesquite::PlanarDomain msq_geom2(s_norm, pnt2); mesh.clear(); mesh.read_vtk(laplacian_file_name_2, err); if (err) return 1; MeshDomainAssoc mesh_and_domain5 = MeshDomainAssoc(&mesh, &msq_geom2); t.reset(); lp_wrapper.run_instructions(&mesh_and_domain5, err); if (err) return 1; double lp_l1_secs = t.since_birth(); std::cout << std::endl << "LaplacianWrapper large file (term crit=0.001) completed in " << lp_l1_secs << " seconds" << std::endl; mesh.clear(); mesh.read_vtk(laplacian_file_name_2, err); if (err) return 1; lp_wrapper.set_vertex_movement_limit_factor(0.1); t.reset(); lp_wrapper.run_instructions(&mesh_and_domain5, err); if (err) return 1; double lp_l2_secs = t.since_birth(); std::cout << std::endl << "LaplacianWrapper large file (term crit=0.1) completed in " << lp_l2_secs << " seconds" << std::endl; // #################### Begin UntangleWrapper::BETA tests ################### mesh.clear(); mesh.read_vtk(untangle_file_name_1, err); if (err) return 1; std::vector<Mesh::VertexHandle> verts; mesh.get_all_vertices( verts, err ); if (err || verts.empty()) return 1; MsqVertex coords; mesh.vertices_get_coordinates( arrptr(verts), &coords, 1, err ); if (err) return 1; Vector3D norm(0,0,1); PlanarDomain u_domain( norm, coords ); UntangleWrapper::UntangleMetric metric = UntangleWrapper::BETA; UntangleWrapper un_wrapper (metric); un_wrapper.set_vertex_movement_limit_factor( 0.005 ); MeshDomainAssoc mesh_and_domain3 = MeshDomainAssoc(&mesh, &u_domain); t.reset(); un_wrapper.run_instructions( &mesh_and_domain3, err ); if (err) return 1; double unb_s_secs = t.since_birth(); std::cout << std::endl << "UntangleWrapper::BETA small file optimization completed in " << unb_s_secs << " seconds" << std::endl; mesh.clear(); mesh.read_vtk(untangle_file_name_2, err); if (err) return 1; // get domain verts.clear(); mesh.get_all_vertices( verts, err ); if (err || verts.empty()) return 1; MsqVertex coords2; mesh.vertices_get_coordinates( arrptr(verts), &coords2, 1, err ); if (err) return 1; PlanarDomain un_domain2( norm, coords2 ); MeshDomainAssoc mesh_and_domain6 = MeshDomainAssoc(&mesh, &un_domain2); t.reset(); un_wrapper.run_instructions( &mesh_and_domain6, err ); if (err) return 1; double unb_l1_secs = t.since_birth(); std::cout << std::endl << "UntangleWrapper::BETA large file (term crit=0.005) completed in " << unb_l1_secs << " seconds" << std::endl; mesh.clear(); mesh.read_vtk(untangle_file_name_2, err); if (err) return 1; // get domain verts.clear(); mesh.get_all_vertices( verts, err ); if (err || verts.empty()) return 1; MsqVertex coords3; mesh.vertices_get_coordinates( arrptr(verts), &coords3, 1, err ); if (err) return 1; PlanarDomain un_domain3( norm, coords3 ); un_wrapper.set_vertex_movement_limit_factor( 0.1 ); MeshDomainAssoc mesh_and_domain7 = MeshDomainAssoc(&mesh, &un_domain3); t.reset(); un_wrapper.run_instructions( &mesh_and_domain7, err ); if (err) return 1; double unb_l2_secs = t.since_birth(); std::cout << std::endl << "UntangleWrapper::BETA large file (term crit=0.1) completed in " << unb_l2_secs << " seconds" << std::endl; // #################### Begin UntangleWrapper::SIZE tests ################### mesh.clear(); mesh.read_vtk(untangle_file_name_1, err); if (err) return 1; verts.clear(); mesh.get_all_vertices( verts, err ); if (err || verts.empty()) return 1; MsqVertex coords2a; mesh.vertices_get_coordinates( arrptr(verts), &coords2a, 1, err ); if (err) return 1; PlanarDomain u_domain3( norm, coords2a ); UntangleWrapper::UntangleMetric metric2 = UntangleWrapper::SIZE; UntangleWrapper un_wrapper2s(metric2); UntangleWrapper un_wrapper2l(metric2); MeshDomainAssoc mesh_and_domain8 = MeshDomainAssoc(&mesh, &u_domain3); t.reset(); un_wrapper2s.run_instructions( &mesh_and_domain8, err ); if (err) return 1; double uns_s_secs = t.since_birth(); std::cout << std::endl << "UntangleWrapper::SIZE small file optimization completed in " << uns_s_secs << " seconds" << std::endl; mesh.clear(); mesh.read_vtk(untangle_file_name_2, err); if (err) return 1; // get domain verts.clear(); mesh.get_all_vertices( verts, err ); if (err || verts.empty()) return 1; MsqVertex coords4; mesh.vertices_get_coordinates( arrptr(verts), &coords4, 1, err ); if (err) return 1; PlanarDomain un_domain4( norm, coords4 ); un_wrapper2s.set_vertex_movement_limit_factor( 0.005 ); MeshDomainAssoc mesh_and_domain9 = MeshDomainAssoc(&mesh, &un_domain4); t.reset(); un_wrapper2s.run_instructions( &mesh_and_domain9, err ); if (err) return 1; double uns_l1_secs = t.since_birth(); std::cout << std::endl << "UntangleWrappe::SIZE large file (term crit=0.005) completed in " << uns_l1_secs << " seconds" << std::endl; mesh.clear(); mesh.read_vtk(untangle_file_name_2, err); if (err) return 1; mesh.get_all_vertices( verts, err ); if (err || verts.empty()) return 1; mesh.vertices_get_coordinates( arrptr(verts), &coords4, 1, err ); if (err) return 1; un_wrapper2l.set_vertex_movement_limit_factor( 0.1 ); t.reset(); un_wrapper2l.run_instructions( &mesh_and_domain9, err ); if (err) return 1; double uns_l2_secs = t.since_birth(); std::cout << std::endl << "UntangleWrappe::SIZE large file (term crit=0.1) completed in " << uns_l2_secs << " seconds" << std::endl; // #################### Begin UntangleWrapper::SHAPESIZE tests ################### mesh.clear(); mesh.read_vtk(untangle_file_name_1, err); if (err) return 1; verts.clear(); mesh.get_all_vertices( verts, err ); if (err || verts.empty()) return 1; MsqVertex coords5; mesh.vertices_get_coordinates( arrptr(verts), &coords5, 1, err ); if (err) return 1; PlanarDomain u_domain5( norm, coords3 ); UntangleWrapper::UntangleMetric metric3 = UntangleWrapper::SHAPESIZE; UntangleWrapper un_wrapper3(metric3); MeshDomainAssoc mesh_and_domain10 = MeshDomainAssoc(&mesh, &u_domain5); t.reset(); un_wrapper3.run_instructions( &mesh_and_domain10, err ); if (err) return 1; double unss_s_secs = t.since_birth(); std::cout << std::endl << "UntangleWrapper::SHAPESIZE small file optimization completed in " << unss_s_secs << " seconds" << std::endl; mesh.clear(); mesh.read_vtk(untangle_file_name_2, err); if (err) return 1; // get domain verts.clear(); mesh.get_all_vertices( verts, err ); if (err || verts.empty()) return 1; MsqVertex coords6; mesh.vertices_get_coordinates( arrptr(verts), &coords6, 1, err ); if (err) return 1; PlanarDomain un_domain6( norm, coords6 ); MeshDomainAssoc mesh_and_domain11 = MeshDomainAssoc(&mesh, &un_domain6); t.reset(); un_wrapper3.run_instructions( &mesh_and_domain11, err ); if (err) return 1; double unss_l_secs = t.since_birth(); std::cout << std::endl << "UntangleWrapper::SHAPESIZE large file optimization completed in " << unss_l_secs << " seconds" << std::endl; // #################### Begin SizeAdaptShapeWrapper tests ################### mesh.clear(); mesh.read_vtk(size_adapt_shape_file_name_1, err); if (err) return 1; elem_vec_t polar, equatorial; find_z10_extreme_elements( mesh, polar, equatorial, err ); if (err) return 1; double eq_min, eq_max, eq_mean, pol_min, pol_max, pol_mean; elem_areas( mesh, polar, pol_min, pol_mean, pol_max, err ); if (err) return 1; elem_areas( mesh, equatorial, eq_min, eq_mean, eq_max, err ); if (err) return 1; SphericalDomain geom( Vector3D(0,0,0), 10.0 ); SizeAdaptShapeWrapper sas_wrapper1(1e-2, 50); SizeAdaptShapeWrapper sas_wrapper2(1e-1, 50); MeshDomainAssoc mesh_and_domain12 = MeshDomainAssoc(&mesh, &geom); t.reset(); sas_wrapper1.run_instructions( &mesh_and_domain12, err); if (err) return 1; double sas1_secs = t.since_birth(); std::cout << std::endl << "SizeAdaptShapeWrapper (term crit=0.01) completed in " << sas1_secs << " seconds" << std::endl; mesh.clear(); mesh.read_vtk(size_adapt_shape_file_name_1, err); if (err) return 1; t.reset(); sas_wrapper2.run_instructions( &mesh_and_domain12, err); if (err) return 1; double sas2_secs = t.since_birth(); std::cout << std::endl << "SizeAdaptShapeWrapper (term crit=0.1) completed in " << sas2_secs << " seconds" << std::endl; // #################### Begin PaverMinEdgeLengthWrapper tests ################### PaverMinEdgeLengthWrapper mel_wrapper1(.005, 50); PaverMinEdgeLengthWrapper mel_wrapper2(.1, 50); mesh.clear(); mesh.read_vtk(min_edge_length_file_name_1, err); t.reset(); mel_wrapper1.run_instructions(&mesh, err); if (err) return 1; double mel_s_secs = t.since_birth(); std::cout << std::endl << "PaverMinEdgeLengthWrapper small file optimization completed in " << mel_s_secs << " seconds" << std::endl; mesh.clear(); mesh.read_vtk(min_edge_length_file_name_2, err); t.reset(); mel_wrapper1.run_instructions(&mesh, err); if (err) return 1; double mel1_l_secs = t.since_birth(); std::cout << std::endl << "PaverMinEdgeLengthWrapper large file (term crit=0.005) completed in " << mel1_l_secs << " seconds" << std::endl; mesh.clear(); mesh.read_vtk(min_edge_length_file_name_2, err); t.reset(); mel_wrapper2.run_instructions(&mesh, err); if (err) return 1; double mel2_l_secs = t.since_birth(); std::cout << std::endl << "PaverMinEdgeLengthWrapper large file (term crit=0.1) completed in " << mel2_l_secs << " seconds" << std::endl; // #################### Begin DeformingDomainWrapper tests ################### // load mesh mesh.clear(); mesh.read_vtk( deforming_domain_file_name_1, err ); if (MSQ_CHKERR(err)) return 1; std::vector<Mesh::VertexHandle> curves[4]; Mesh::VertexHandle corners[4]; classify_boundary( &mesh, corners, curves, err ); if (MSQ_CHKERR(err)) return 1; // new, "deformed" domain will be an 2HDx2HD planar square const double corner_coords[][3] = { {-HD,-HD, Z}, { HD,-HD, Z}, { HD, HD, Z}, {-HD, HD, Z} }; LineDomain lines[4] = { LineDomain( Vector3D(corner_coords[0]), Vector3D( 1, 0, 0) ), LineDomain( Vector3D(corner_coords[1]), Vector3D( 0, 1, 0) ), LineDomain( Vector3D(corner_coords[2]), Vector3D(-1, 0, 0) ), LineDomain( Vector3D(corner_coords[3]), Vector3D( 0,-1, 0) ) }; PlanarDomain surface( PlanarDomain::XY, Z ); // save initial mesh state DeformingCurveSmoother curve_tool; for (int i = 0; i < 4; ++i) { curve_tool.store_initial_mesh( &mesh, &curves[i][0], curves[i].size(), &lines[i], err ); if (MSQ_CHKERR(err)) return 1; } DeformingDomainWrapper dd_wrapper; dd_wrapper.store_initial_mesh( &mesh, err ); if (MSQ_CHKERR(err)) return 1; // move corner vertices to new location for (int i = 0; i < 4; ++i) { Vector3D vect(corner_coords[i]); mesh.vertex_set_coordinates( corners[i], vect, err ); if (MSQ_CHKERR(err)) return 1; } std::vector<bool> fixed(4,true); mesh.vertices_set_fixed_flag( corners, fixed, 4, err ); if (MSQ_CHKERR(err)) return 1; // smooth curves for (int i = 0; i < 4; ++i) { curve_tool.smooth_curve( &mesh, &curves[i][0], curves[i].size(), &lines[i], DeformingCurveSmoother::PROPORTIONAL, err ); if (MSQ_CHKERR(err)) return 1; fixed.resize(curves[i].size(),true); mesh.vertices_set_fixed_flag( &curves[i][0], fixed, curves[i].size(), err ); if (MSQ_CHKERR(err)) return 1; } MeshDomainAssoc mesh_and_domain1 = MeshDomainAssoc(&mesh, &surface); t.reset(); dd_wrapper.run_instructions( &mesh_and_domain1, err ); if (MSQ_CHKERR(err)) return 1; double dd_secs = t.since_birth(); std::cout << std::endl << "DeformingDomainWrapper file (term crit=0.01) completed in " << dd_secs << " seconds" << std::endl; // Do it all again for the next test mesh.clear(); mesh.read_vtk( deforming_domain_file_name_1, err ); if (MSQ_CHKERR(err)) return 1; std::vector<Mesh::VertexHandle> curves2[4]; Mesh::VertexHandle corners2[4]; classify_boundary( &mesh, corners2, curves2, err ); if (MSQ_CHKERR(err)) return 1; // new, "deformed" domain will be an 2HDx2HD planar square const double corner_coords2[][3] = { {-HD,-HD, Z}, { HD,-HD, Z}, { HD, HD, Z}, {-HD, HD, Z} }; LineDomain lines2[4] = { LineDomain( Vector3D(corner_coords2[0]), Vector3D( 1, 0, 0) ), LineDomain( Vector3D(corner_coords2[1]), Vector3D( 0, 1, 0) ), LineDomain( Vector3D(corner_coords2[2]), Vector3D(-1, 0, 0) ), LineDomain( Vector3D(corner_coords2[3]), Vector3D( 0,-1, 0) ) }; PlanarDomain surface2( PlanarDomain::XY, Z ); // save initial mesh state DeformingCurveSmoother curve_tool2; for (int i = 0; i < 4; ++i) { curve_tool2.store_initial_mesh( &mesh, &curves2[i][0], curves2[i].size(), &lines2[i], err ); if (MSQ_CHKERR(err)) return 1; } DeformingDomainWrapper dd_wrapper2; dd_wrapper2.store_initial_mesh( &mesh, err ); if (MSQ_CHKERR(err)) return 1; // move corner vertices to new location for (int i = 0; i < 4; ++i) { Vector3D vect(corner_coords2[i]); mesh.vertex_set_coordinates( corners2[i], vect, err ); if (MSQ_CHKERR(err)) return 1; } std::vector<bool> fixed2(4,true); mesh.vertices_set_fixed_flag( corners2, fixed2, 4, err ); if (MSQ_CHKERR(err)) return 1; // smooth curves for (int i = 0; i < 4; ++i) { curve_tool2.smooth_curve( &mesh, &curves2[i][0], curves2[i].size(), &lines2[i], DeformingCurveSmoother::PROPORTIONAL, err ); if (MSQ_CHKERR(err)) return 1; fixed2.resize(curves2[i].size(),true); mesh.vertices_set_fixed_flag( &curves2[i][0], fixed2, curves2[i].size(), err ); if (MSQ_CHKERR(err)) return 1; } dd_wrapper2.set_vertex_movement_limit_factor(0.1); MeshDomainAssoc mesh_and_domain2 = MeshDomainAssoc(&mesh, &surface2); t.reset(); dd_wrapper2.run_instructions( &mesh_and_domain2, err ); if (MSQ_CHKERR(err)) return 1; double dd_secs2 = t.since_birth(); std::cout << std::endl << "DeformingDomainWrapper file (term crit=0.1) completed in " << dd_secs2 << " seconds" << std::endl; // Timing Summary std::cout << std::endl << "********* Wrappers Timing Summary **********" << std::endl << "Version " << version_string(true) << std::endl << std::endl; std::cout << "ShapeImprover small file optimization completed in " << si_s_secs << " seconds" << std::endl; std::cout << "ShapeImprover large file optimization completed in " << si_l_secs << " seconds" << std::endl; std::cout << "LaplacianWrapper small file optimization completed in " << lp_s_secs << " seconds" << std::endl; std::cout << "LaplacianWrapper large file optimization (term crit=0.001) in " << lp_l1_secs << " seconds" << std::endl; std::cout << "LaplacianWrapper large file optimization (term crit=0.1) in " << lp_l2_secs << " seconds" << std::endl; std::cout << "UntangleWrapper::BETA small file optimization completed in " << unb_s_secs << " seconds" << std::endl; std::cout << "UntangleWrapper::BETA large file (term crit=0.005) completed in " << unb_l1_secs << " seconds" << std::endl; std::cout << "UntangleWrapper::BETA large file (term crit=0.1) completed in " << unb_l2_secs << " seconds" << std::endl; std::cout << "UntangleWrapper::SIZE small file optimization completed in " << uns_s_secs << " seconds" << std::endl; std::cout << "UntangleWrapper::SIZE large file (term crit=0.005) completed in " << uns_l1_secs << " seconds" << std::endl; std::cout << "UntangleWrapper::SIZE large file (term crit=0.1) completed in " << uns_l2_secs << " seconds" << std::endl; std::cout << "UntangleWrapper::SHAPESIZE small file optimization completed in " << unss_s_secs << " seconds" << std::endl; std::cout << "UntangleWrapper::SHAPESIZE large file optimization completed in " << unss_l_secs << " seconds" << std::endl; std::cout << "SizeAdaptShapeWrapper (term crit=0.01) completed in " << sas1_secs << " seconds" << std::endl; std::cout << "SizeAdaptShapeWrapper (term crit=0.1) completed in " << sas2_secs << " seconds" << std::endl; std::cout << "PaverMinEdgeLengthWrapper small file optimization completed in " << mel_s_secs << " seconds" << std::endl; std::cout << "PaverMinEdgeLengthWrapper large file (term crit=0.005) completed in " << mel1_l_secs << " seconds" << std::endl; std::cout << "PaverMinEdgeLengthWrapper large file (term crit=0.1) completed in " << mel2_l_secs << " seconds" << std::endl; std::cout << "DeformingDomainWrapper file (term crit=0.01) completed in " << dd_secs << " seconds" << std::endl; std::cout << "DeformingDomainWrapper file (term crit=0.1) completed in " << dd_secs2 << " seconds" << std::endl; return 0; }
int main(int argc, char* argv[]) { const char* input_file = DEFAULT_INPUT; const char* output_file = NULL; switch (argc) { default: help(argv[0]); case 3: if (!strcmp(argv[2],"-h")) help(argv[0]); output_file = argv[2]; case 2: if (!strcmp(argv[1],"-h")) help(argv[0]); input_file = argv[1]; case 1: ; } /* Read a VTK Mesh file */ MsqPrintError err(cout); Mesquite::MeshImpl mesh; mesh.read_vtk( input_file, err); if (err) return 1; // creates an intruction queue InstructionQueue queue1; // creates a mean ratio quality metric ... ConditionNumberQualityMetric shape_metric; EdgeLengthQualityMetric lapl_met; lapl_met.set_averaging_method(QualityMetric::RMS); // creates the laplacian smoother procedures LaplacianSmoother lapl1; QualityAssessor stop_qa=QualityAssessor(&shape_metric); stop_qa.add_quality_assessment(&lapl_met); //**************Set stopping criterion**************** TerminationCriterion sc2; sc2.add_iteration_limit( 10 ); if (err) return 1; lapl1.set_outer_termination_criterion(&sc2); // adds 1 pass of pass1 to mesh_set1 queue1.add_quality_assessor(&stop_qa,err); if (err) return 1; queue1.set_master_quality_improver(&lapl1, err); if (err) return 1; queue1.add_quality_assessor(&stop_qa,err); if (err) return 1; // adds 1 passes of pass2 to mesh_set1 // mesh_set1.add_quality_pass(pass2); //writeVtkMesh("original_mesh", mesh, err); MSQ_CHKERR(err); PlanarDomain plane(Vector3D(0,0,1), Vector3D(0,0,5)); // launches optimization on mesh_set1 MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &plane); Timer t; queue1.run_instructions(&mesh_and_domain, err); if (err) return 1; double secs = t.since_birth(); std::cout << "Optimization completed in " << secs << " seconds" << std::endl; if (output_file) { mesh.write_vtk(output_file, err); if (err) return 1; std::cout << "Wrote file: " << output_file << std::endl; } // check that smoother is working: // the one free vertex must be at the origin if (input_file == DEFAULT_INPUT) { std::vector<Mesh::VertexHandle> vertices; mesh.get_all_vertices( vertices, err ); if (err) return 1; std::vector<bool> fixed_flags; mesh.vertices_get_fixed_flag( arrptr(vertices), fixed_flags, vertices.size(), err ); if (err) return 1; // find one free vertex int idx = -1; for (unsigned i = 0; i < vertices.size(); ++i) { if (fixed_flags[i] == true) continue; if (idx != -1) { std::cerr << "Multiple free vertices in mesh." << std::endl; return 1; } idx = i; } if (idx == -1) { std::cerr << "No free vertex in mesh!!!!!" << std::endl; return 1; } Mesh::VertexHandle vertex = vertices[idx]; MsqVertex coords; mesh.vertices_get_coordinates( &vertex, &coords, 1, err ); if (err) return 1; // calculate distance from origin double dist = sqrt( coords[0]*coords[0] + coords[1]*coords[1] ); if (dist > 1e-8) { std::cerr << "Free vertex not at origin after Laplace smooth." << std::endl << "Expected location: (0,0)" << std::endl << "Actual location: (" << coords[0] << "," << coords[1] << ")" << std::endl; return 2; } } return 0; }