void VolumeViewer::addGeometry(std::string filename) { // For now we assume PLY geometry files. Later we can support other geometry formats. // Get filename if not specified. if(filename.empty()) filename = QFileDialog::getOpenFileName(this, tr("Load geometry"), ".", "Geometry files (*.ply *.dds)").toStdString(); if(filename.empty()) return; // Attempt to load the geometry through the TriangleMeshFile loader. OSPGeometry triangleMesh = ospNewGeometry("trianglemesh"); // If successful, commit the triangle mesh and add it to all models. if(TriangleMeshFile::importTriangleMesh(filename, triangleMesh) != NULL) { // For now: if this is a DDS geometry, assume it is a horizon and its color should be mapped through the first volume's transfer function. if(QString(filename.c_str()).endsWith(".dds") && modelStates.size() > 0 && modelStates[0].volumes.size() > 0) { OSPMaterial material = ospNewMaterial(renderer, "default"); ospSet3f(material, "Kd", 1,1,1); ospSetObject(material, "volume", modelStates[0].volumes[0]); ospCommit(material); ospSetMaterial(triangleMesh, material); } ospCommit(triangleMesh); // Create an instance of the geometry and add the instance to the main model(s)--this prevents the geometry // from being rebuilt every time the main model is committed (e.g. when slices / isosurfaces are manipulated) OSPModel modelInstance = ospNewModel(); ospAddGeometry(modelInstance, triangleMesh); ospCommit(modelInstance); ospcommon::affine3f xfm = ospcommon::one; OSPGeometry triangleMeshInstance = ospNewInstance(modelInstance, (osp::affine3f&)xfm); ospCommit(triangleMeshInstance); for(size_t i=0; i<modelStates.size(); i++) { ospAddGeometry(modelStates[i].model, triangleMeshInstance); ospCommit(modelStates[i].model); } // Force render. render(); } }
void VolumeViewer::setIsovalues(std::vector<float> isovalues) { OSPData isovaluesData = ospNewData(isovalues.size(), OSP_FLOAT, &isovalues[0]); // Remove existing isosurface geometries from models. for(size_t i=0; i<modelStates.size(); i++) { for(size_t j=0; j<modelStates[i].isosurfaces.size(); j++) ospRemoveGeometry(modelStates[i].model, modelStates[i].isosurfaces[j]); modelStates[i].isosurfaces.clear(); } // Add new isosurfaces for each volume of each model. Later we can do this only for the active model on time step change... for(size_t i=0; i<modelStates.size(); i++) { if(isovalues.size() > 0) { for(size_t j=0; j<modelStates[i].volumes.size(); j++) { OSPGeometry isosurfacesGeometry = ospNewGeometry("isosurfaces"); ospSetData(isosurfacesGeometry, "isovalues", isovaluesData); ospSetObject(isosurfacesGeometry, "volume", modelStates[i].volumes[j]); ospCommit(isosurfacesGeometry); ospAddGeometry(modelStates[i].model, isosurfacesGeometry); modelStates[i].isosurfaces.push_back(isosurfacesGeometry); } } ospCommit(modelStates[i].model); } render(); }
void VolumeViewer::importObjectsFromFile(const std::string &filename) { if (!ownModelPerObject) // Create an OSPRay model and its associated model state. modelStates.push_back(ModelState(ospNewModel())); // Load OSPRay objects from a file. OSPObject *objects = ObjectFile::importObjects(filename.c_str()); // Iterate over the objects contained in the object list. for (size_t i=0 ; objects[i] ; i++) { if (ownModelPerObject) modelStates.push_back(ModelState(ospNewModel())); OSPDataType type; ospGetType(objects[i], NULL, &type); if (type == OSP_GEOMETRY) { // Commit the geometry. ospCommit(objects[i]); // Add the loaded geometry to the model. ospAddGeometry(modelStates.back().model, (OSPGeometry) objects[i]); } else if (type == OSP_VOLUME) { // For now we set the same transfer function on all volumes. ospSetObject(objects[i], "transferFunction", transferFunction); ospCommit(objects[i]); // Add the loaded volume(s) to the model. ospAddVolume(modelStates.back().model, (OSPVolume) objects[i]); // Add to volumes vector for the current model. modelStates.back().volumes.push_back((OSPVolume) objects[i]); } if (ownModelPerObject) ospCommit(modelStates.back().model); } if (!ownModelPerObject) // Commit the model. ospCommit(modelStates.back().model); }
void VolumeViewer::setSlices(std::vector<SliceParameters> sliceParameters) { // Provide the slices to OSPRay as the coefficients (a,b,c,d) of the plane equation ax + by + cz + d = 0. std::vector<ospcommon::vec4f> planes; for(size_t i=0; i<sliceParameters.size(); i++) planes.push_back(ospcommon::vec4f(sliceParameters[i].normal.x, sliceParameters[i].normal.y, sliceParameters[i].normal.z, -dot(sliceParameters[i].origin, sliceParameters[i].normal))); OSPData planesData = ospNewData(planes.size(), OSP_FLOAT4, &planes[0].x); // Remove existing slice geometries from models. for(size_t i=0; i<modelStates.size(); i++) { for(size_t j=0; j<modelStates[i].slices.size(); j++) ospRemoveGeometry(modelStates[i].model, modelStates[i].slices[j]); modelStates[i].slices.clear(); } // Add new slices for each volume of each model. Later we can do this only for the active model on time step change... for(size_t i=0; i<modelStates.size(); i++) { if(planes.size() > 0) { for(size_t j=0; j<modelStates[i].volumes.size(); j++) { OSPGeometry slicesGeometry = ospNewGeometry("slices"); ospSetData(slicesGeometry, "planes", planesData); ospSetObject(slicesGeometry, "volume", modelStates[i].volumes[j]); ospCommit(slicesGeometry); ospAddGeometry(modelStates[i].model, slicesGeometry); modelStates[i].slices.push_back(slicesGeometry); } } ospCommit(modelStates[i].model); } render(); }
void Geometry::postRender(RenderContext& ctx) { auto ospGeometry = valueAs<OSPGeometry>(); if (ospGeometry) ospAddGeometry(ctx.currentOSPModel, ospGeometry); }
int main(int ac, const char **av) { // image size osp_vec2i imgSize; imgSize.x = 1024; // width imgSize.y = 768; // height // camera float cam_pos[] = {0.f, 0.f, 0.f}; float cam_up [] = {0.f, 1.f, 0.f}; float cam_view [] = {0.1f, 0.f, 1.f}; // triangle mesh data float vertex[] = { -1.0f, -1.0f, 3.0f, 0.f, -1.0f, 1.0f, 3.0f, 0.f, 1.0f, -1.0f, 3.0f, 0.f, 0.1f, 0.1f, 0.3f, 0.f }; float color[] = { 0.9f, 0.5f, 0.5f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f, 0.5f, 0.9f, 0.5f, 1.0f }; int32_t index[] = { 0, 1, 2, 1, 2, 3 }; // initialize OSPRay; OSPRay parses (and removes) its commandline parameters, e.g. "--osp:debug" ospInit(&ac, av); // create and setup camera OSPCamera camera = ospNewCamera("perspective"); ospSetf(camera, "aspect", imgSize.x/(float)imgSize.y); ospSet3fv(camera, "pos", cam_pos); ospSet3fv(camera, "dir", cam_view); ospSet3fv(camera, "up", cam_up); ospCommit(camera); // commit each object to indicate modifications are done // create and setup model and mesh OSPGeometry mesh = ospNewGeometry("triangles"); OSPData data = ospNewData(4, OSP_FLOAT3A, vertex, 0); // OSP_FLOAT3 format is also supported for vertex positions (currently not on MIC) ospCommit(data); ospSetData(mesh, "vertex", data); data = ospNewData(4, OSP_FLOAT4, color, 0); ospCommit(data); ospSetData(mesh, "vertex.color", data); data = ospNewData(2, OSP_INT3, index, 0); // OSP_INT4 format is also supported for triangle indices ospCommit(data); ospSetData(mesh, "index", data); ospCommit(mesh); OSPModel world = ospNewModel(); ospAddGeometry(world, mesh); ospCommit(world); // create and setup renderer OSPRenderer renderer = ospNewRenderer("scivis"); // choose Scientific Visualization renderer ospSet1f(renderer, "aoWeight", 1.0f); // with full Ambient Occlusion ospSet1i(renderer, "aoSamples", 1); ospSetObject(renderer, "model", world); ospSetObject(renderer, "camera", camera); ospCommit(renderer); // create and setup framebuffer OSPFrameBuffer framebuffer = ospNewFrameBuffer(&imgSize, OSP_FB_SRGBA, OSP_FB_COLOR | /*OSP_FB_DEPTH |*/ OSP_FB_ACCUM); ospFrameBufferClear(framebuffer, OSP_FB_COLOR | OSP_FB_ACCUM); // render one frame ospRenderFrame(framebuffer, renderer, OSP_FB_COLOR | OSP_FB_ACCUM); // access framebuffer and write its content as PPM file const uint32_t * fb = (uint32_t*)ospMapFrameBuffer(framebuffer, OSP_FB_COLOR); writePPM("firstFrameC.ppm", &imgSize, fb); ospUnmapFrameBuffer(fb, framebuffer); // render 10 more frames, which are accumulated to result in a better converged image for (int frames = 0; frames < 10; frames++) ospRenderFrame(framebuffer, renderer, OSP_FB_COLOR | OSP_FB_ACCUM); fb = (uint32_t*)ospMapFrameBuffer(framebuffer, OSP_FB_COLOR); writePPM("accumulatedFrameC.ppm", &imgSize, fb); ospUnmapFrameBuffer(fb, framebuffer); return 0; }