示例#1
0
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();
}
示例#2
0
    void Geometry::preCommit(RenderContext &)
    {
      auto ospGeometry = valueAs<OSPGeometry>();
      if (!ospGeometry) {
        auto type = child("type").valueAs<std::string>();
        ospGeometry = ospNewGeometry(type.c_str());
        setValue(ospGeometry);

        child("bounds") = computeBounds();
      }
    }
示例#3
0
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();
  }
}
OSPGeometry OSPObjectFile::importTriangleMesh(const tinyxml2::XMLNode *root)
{
  // Create the OSPRay object.
  OSPGeometry triangleMesh = ospNewGeometry("trianglemesh");

  // Temporary storage for the file name attribute if specified.
  const char *triangleMeshFilename = NULL;

  // Iterate over object attributes.
  for (const tinyxml2::XMLNode *node = root->FirstChild() ; node ; node = node->NextSibling()) {

    // File containing a triangle mesh specification and / or data.
    if (!strcmp(node->ToElement()->Name(), "filename")) { triangleMeshFilename = node->ToElement()->GetText();  continue; }

    // Scaling for vertex coordinates.
    if (!strcmp(node->ToElement()->Name(), "scale")) { importAttributeFloat3(node, triangleMesh);  continue; }
    
    // Error check.
    exitOnCondition(true, "unrecognized XML element type '" + std::string(node->ToElement()->Name()) + "'");
  }

  // Load the contents of the triangle mesh file if specified.
  if (triangleMeshFilename != NULL) {

    // Some implementations of 'dirname()' are destructive.
    char *duplicateFilename = strdup(filename.c_str());

    // The triangle mesh file path is absolute.
    if (triangleMeshFilename[0] == '/') {
      return(TriangleMeshFile::importTriangleMesh(triangleMeshFilename,
                                                  triangleMesh));
    }

    // The triangle mesh file path is relative to the object file path.
    if (triangleMeshFilename[0] != '/') {
      return(TriangleMeshFile::importTriangleMesh((std::string(dirname(duplicateFilename)) + "/" + triangleMeshFilename).c_str(), triangleMesh));
    }

    // Free the temporary character array.
    if (duplicateFilename != NULL) free(duplicateFilename);
  }

  // The populated triangle mesh object.
  return triangleMesh;
}
示例#5
0
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();
}
示例#6
0
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;
}