void Voxelizer::ShapeVoxelizer::voxelize() { std::cerr << "Begin voxelization" << std::endl; std::cerr << "Matching faces to grid" << std::endl; for (const glm::vec3& face : m_shape.mesh.faces) { const glm::vec3& face_vertex_x = m_shape.mesh.vertices[face.x]; const glm::vec3& face_vertex_y = m_shape.mesh.vertices[face.y]; const glm::vec3& face_vertex_z = m_shape.mesh.vertices[face.z]; glm::vec3 x(face_vertex_x.x, face_vertex_x.y, face_vertex_x.z); glm::vec3 y(face_vertex_y.x, face_vertex_y.y, face_vertex_y.z); glm::vec3 z(face_vertex_z.x, face_vertex_z.y, face_vertex_z.z); voxelize(x, y, z); } if (Legoizer::shouldFillShell) { fillShell(); } std::cerr << "Adding to grid" << std::endl; save(); std::cerr << "Finished voxelization" << std::endl; }
void SPHSystem::writeFrame(float* c = 0) { for (int i = 0; i < n; ++i) { Vec x = p[i]; float ci = c ? c[i] : 0; //cout << p[i].x << ' ' << p[i].y << ' '<< p[i].z << ' ' << ci << endl; logstream.write(reinterpret_cast<const char*>(&x.x), sizeof(float)); logstream.write(reinterpret_cast<const char*>(&x.y), sizeof(float)); logstream.write(reinterpret_cast<const char*>(&x.z), sizeof(float)); logstream.write(reinterpret_cast<const char*>(&ci), sizeof(float)); } vector<float> voxels = voxelize(64, 64, 64); // write the voxels to a file stringstream ss; ss << "frame" << curframe << ".bin"; cout << "writing file " << ss.str() << " with " << voxels.size() << " voxels." << endl; ofstream fout(ss.str(), ios::binary); fout.write(reinterpret_cast<const char*>(&voxels[0]), sizeof(float)*voxels.size()); fout.close(); CIsoSurface<float> mc; cout << "extracing mesh with marching cubes ..." << endl; mc.GenerateSurface(&voxels[0], 1.0f, 63, 63, 63, 1.0, 1.0, 1.0); cout << "done." << endl; stringstream ss2; ss2 << "frame" << curframe << ".obj"; cout << "writing file " << ss2.str() << endl; mc.writeToFile(ss2.str()); }
/* * M A I N */ int main(int argc, char **argv) { static struct rt_i *rtip; fastf_t sizeVoxel[3], threshold; int levelOfDetail; genptr_t callBackData; char title[1024] = {0}; /* Check for command-line arguments. Make sure we have at least a * geometry file and one geometry object on the command line. */ if (argc < 3) { bu_exit(1, "Usage: %s model.g objects...\n", argv[0]); } /* Load the specified geometry database (i.e., a ".g" file). * rt_dirbuild() returns an "instance" pointer which describes the * database to be raytraced. It also gives you back the title * string if you provide a buffer. This builds a directory of the * geometry (i.e., a table of contents) in the file. */ rtip = rt_dirbuild(argv[1], title, sizeof(title)); if (rtip == RTI_NULL) { bu_exit(2, "Building the database directory for [%s] FAILED\n", argv[1]); } /* Walk the geometry trees. Here you identify any objects in the * database that you want included in the ray trace by iterating * of the object names that were specified on the command-line. */ while (argc > 2) { if (rt_gettree(rtip, argv[2]) < 0) bu_log("Loading the geometry for [%s] FAILED\n", argv[2]); argc--; argv++; } /* user parameters are being given values directly here*/ sizeVoxel[0] = 1.0; sizeVoxel[1] = 1.0; sizeVoxel[2] = 1.0; threshold = 0.5; levelOfDetail = 4; callBackData = (void *)(& threshold); /* voxelize function is called here with rtip(ray trace instance), userParameters and printToFile/printToScreen options */ voxelize(rtip, sizeVoxel, levelOfDetail, printToFile, callBackData); rt_free_rti(rtip); return 0; }
void Voxelizer::ShapeVoxelizer::voxelize( glm::vec3& v1, glm::vec3& v2, glm::vec3& v3 ) { // scale model to NxNxN grid glm::vec3 p1 = glm::vec3( (v1.x - m_min.x) / m_unit, (v1.y - m_min.y) / (m_unit * Voxelizer::scale()), (v1.z - m_min.z) / m_unit ); glm::vec3 p2 = glm::vec3( (v2.x - m_min.x) / m_unit, (v2.y - m_min.y) / (m_unit * Voxelizer::scale()), (v2.z - m_min.z) / m_unit ); glm::vec3 p3 = glm::vec3( (v3.x - m_min.x) / m_unit, (v3.y - m_min.y) / (m_unit * Voxelizer::scale()), (v3.z - m_min.z) / m_unit ); if (arePointsClose(p1, p2, p3) && arePointsOnOccupiedVoxel(p1, p2, p3)){ return; } m_grid[(size_t)p1.x][(size_t)p1.y][(size_t)p1.z] = 1; m_grid[(size_t)p2.x][(size_t)p2.y][(size_t)p2.z] = 1; m_grid[(size_t)p3.x][(size_t)p3.y][(size_t)p3.z] = 1; glm::vec3 mid1 = glm_helpers::midpoint(v1, v2); glm::vec3 mid2 = glm_helpers::midpoint(v2, v3); glm::vec3 mid3 = glm_helpers::midpoint(v1, v3); voxelize(v1, mid1, mid3); voxelize(mid1, v2, mid2); voxelize(mid3, mid2, v3); voxelize(mid1, mid2, mid3); }
virtual void call() { // clear old voxelizations if any clear(); // voxelize scene voxelize(); // generate nodes generateRenderableNodes(); // update renderpasses with new geometry updateRenderPasses(); }
int ged_voxelize(struct ged *gedp, int argc, const char *argv[]) { struct rt_i *rtip; static const char *usage = "[-s \"dx dy dz\"] [-d n] [-t f] new_obj old_obj [old_obj2 old_obj3 ...]"; fastf_t sizeVoxel[3]; int levelOfDetail; genptr_t callBackData; struct voxelizeData voxDat; int c; /* intentionally double for scan */ double threshold; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialization */ bu_vls_trunc(gedp->ged_result_str, 0); /* incorrect arguments */ if (argc < 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } sizeVoxel[0] = 1.0; sizeVoxel[1] = 1.0; sizeVoxel[2] = 1.0; levelOfDetail = 1; threshold = 0.5; bu_optind = 1; while ((c = bu_getopt(argc, (char * const *)argv, (const char *)"s:d:t:")) != -1) { double scan[3]; switch (c) { case 's': if (sscanf(bu_optarg, "%lf %lf %lf", &scan[0], &scan[1], &scan[2]) != 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } else { /* convert from double to fastf_t */ VMOVE(sizeVoxel, scan); sizeVoxel[0] = sizeVoxel[0] * gedp->ged_wdbp->dbip->dbi_local2base; sizeVoxel[1] = sizeVoxel[1] * gedp->ged_wdbp->dbip->dbi_local2base; sizeVoxel[2] = sizeVoxel[2] * gedp->ged_wdbp->dbip->dbi_local2base; } break; case 'd': if (sscanf(bu_optarg, "%d", &levelOfDetail) != 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } break; case 't': if(sscanf(bu_optarg, "%lf", &threshold) != 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } break; default: bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } } argc -= bu_optind; argv += bu_optind; if (argc < 2) { bu_vls_printf(gedp->ged_result_str, "error: missing argument(s)\n"); return GED_ERROR; } voxDat.newname = (char *)argv[0]; argc--; argv++; if (db_lookup(gedp->ged_wdbp->dbip, voxDat.newname, LOOKUP_QUIET) != RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "error: solid '%s' already exists, aborting\n", voxDat.newname); return GED_ERROR; } rtip = rt_new_rti(gedp->ged_wdbp->dbip); rtip->useair = 1; /* Walk trees. Here we identify any object trees in the database * that the user wants included in the ray trace. */ while(argc > 0) { if(rt_gettree(rtip,argv[0]) < 0) { bu_vls_printf(gedp->ged_result_str, "error: object '%s' does not exists, aborting\n", argv[1]); return GED_ERROR; } argc--; argv++; } voxDat.sizeVoxel[0] = sizeVoxel[0]; voxDat.sizeVoxel[1] = sizeVoxel[1]; voxDat.sizeVoxel[2] = sizeVoxel[2]; voxDat.threshold = threshold; voxDat.wdbp = gedp->ged_wdbp; voxDat.bbMin = rtip->mdl_min; BU_LIST_INIT(&voxDat.content.l); callBackData = (void*)(&voxDat); /* voxelize function is called here with rtip(ray trace instance), userParameter and create_boxes function */ voxelize(rtip, sizeVoxel, levelOfDetail, create_boxes, callBackData); mk_comb(gedp->ged_wdbp, voxDat.newname, &voxDat.content.l, 1, "plastic", "sh=4 sp=0.5 di=0.5 re=0.1", 0, 1000, 0, 0, 100, 0, 0, 0); mk_freemembers(&voxDat.content.l); rt_free_rti(rtip); return GED_OK; }