bool obj_save(const string& filename, Manifold& m) { ofstream os(filename.data()); if(os.bad()) return false; VertexAttributeVector<int> vmap; int k = 0; for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v){ Vec3d p = m.pos(*v); os << "v "<< p[0] << " " << p[1] << " " << p[2] << "\n"; vmap[*v] = k++; } for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f){ vector<int> verts; for(Walker w = m.walker(*f); !w.full_circle(); w = w.circulate_face_ccw()){ int idx = vmap[w.vertex()]; assert(static_cast<size_t>(idx) < m.no_vertices()); // move subscript range from 0..size-1 to 1..size according to OBJ standards verts.push_back(idx + 1); } os << "f "; for(size_t i = 0; i < verts.size() ; ++i){ os << verts[i] << " "; } os<<endl; } return true; }
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; }