void quadric_simplify(Manifold& m, double keep_fraction, double singular_thresh, bool choose_optimal_positions) { gel_srand(1210); long int F = m.no_faces(); VertexAttributeVector<int> mask(m.no_faces(), 0); long int max_work = max(static_cast<long int>(0), F- static_cast<long int>(keep_fraction * F)); QuadricSimplifier qsim(m, mask, singular_thresh, choose_optimal_positions); qsim.reduce(max_work); }
void dual(Manifold& m) { // Create new vertices. Each face becomes a vertex whose position // is the centre of the face int i = 0; FaceAttributeVector<int> ftouched; vector<Vec3d> vertices; vertices.resize(m.no_faces()); for(auto f : m.faces()) vertices[ftouched[f] = i++] = centre(m, f); // Create new faces. Each vertex is a new face with N=valency of vertex // edges. vector<int> faces; vector<int> indices; for(auto v : m.vertices()) if(valency(m, v) > 2 && !(boundary(m, v))) { // int N = circulate_vertex_ccw(m, v, (std::function<void(FaceID)>)[&](FaceID fid) { // indices.push_back(ftouched[fid]); // }); Walker w = m.walker(v); for(; !w.full_circle(); w = w.circulate_vertex_ccw()){ indices.push_back(ftouched[w.face()]); } int N = w.no_steps(); // Insert face valency in the face vector. faces.push_back(N); } // Clear the manifold before new geometry is inserted. m.clear(); // And build m.build( vertices.size(), reinterpret_cast<double*>(&vertices[0]), faces.size(), &faces[0], &indices[0]); }
int main(int argc, char** argv) { // LOAD OBJ Manifold m; if(argc>1) { ArgExtracter ae(argc, argv); do_aabb = ae.extract("-A"); do_obb = ae.extract("-O"); ae.extract("-x", vol_dim[0]); ae.extract("-y", vol_dim[1]); ae.extract("-z", vol_dim[2]); do_ray_tests = ae.extract("-R"); flip_normals = ae.extract("-f"); string file = ae.get_last_arg(); cout << "loading " << file << "... " << flush; load(file, m); cout << " done" << endl; } else { string fn("../../data/bunny-little.x3d"); x3d_load(fn, m); } cout << "Volume dimensions " << vol_dim << endl; if(!valid(m)) { cout << "Not a valid manifold" << endl; exit(0); } triangulate_by_edge_face_split(m); Vec3d p0, p7; bbox(m, p0, p7); Mat4x4d T = fit_bounding_volume(p0,p7,10); cout << "Transformation " << T << endl; for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v) m.pos(*v) = T.mul_3D_point(m.pos(*v)); RGridf grid(vol_dim,FLT_MAX); Util::Timer tim; float T_build_obb=0, T_build_aabb=0, T_dist_obb=0, T_dist_aabb=0, T_ray_obb=0, T_ray_aabb=0; if(do_obb) { cout << "Building OBB Tree" << endl; tim.start(); OBBTree obb_tree; build_OBBTree(m, obb_tree); T_build_obb = tim.get_secs(); cout << "Computing distances from OBB Tree" << endl; tim.start(); DistCompCache<OBBTree> dist(&obb_tree); for_each_voxel(grid, dist); T_dist_obb = tim.get_secs(); cout << "Saving distance field" << endl; save_raw_float("obb_dist.raw", grid); if(do_ray_tests) { cout << "Ray tests on OBB Tree" << endl; tim.start(); RayCast<OBBTree> ray(&obb_tree); for_each_voxel(grid, ray); T_ray_obb = tim.get_secs(); cout << "Saving ray volume" << endl; save_raw_float("obb_ray.raw", grid); } } if(do_aabb) { cout << "Building AABB Tree" << endl; tim.start(); AABBTree aabb_tree; build_AABBTree(m, aabb_tree); T_build_aabb = tim.get_secs(); cout << "Computing distances from AABB Tree" << endl; tim.start(); DistCompCache<AABBTree> dist(&aabb_tree); for_each_voxel(grid, dist); T_dist_aabb = tim.get_secs(); cout << "Saving distance field" << endl; save_raw_float("aabb_dist.raw", grid); if(do_ray_tests) { cout << "Ray tests on AABB tree" << endl; tim.start(); RayCast<AABBTree> ray(&aabb_tree); for_each_voxel(grid, ray); T_ray_aabb = tim.get_secs(); cout << "Saving ray volume" << endl; save_raw_float("aabb_ray.raw", grid); } } cout.width(10); cout << "Poly"; cout.width(11); cout <<"build_obb"; cout.width(12); cout << "build_aabb"; cout.width(10); cout << "dist_obb" ; cout.width(10); cout << "dist_aabb"; cout.width(10); cout << "ray_obb" ; cout.width(10); cout << "ray_aabb"; cout << endl; cout.precision(4); cout.width(10); cout << m.no_faces() << " "; cout.width(10); cout << T_build_obb; cout.width(12); cout << T_build_aabb; cout.width(10); cout << T_dist_obb; cout.width(10); cout << T_dist_aabb; cout.width(10); cout << T_ray_obb; cout.width(10); cout << T_ray_aabb; cout << endl; }