// Create a volume rendering node with all desired attachments
NodePtr makeVolume(ImagePtr datImage)
{  
    vol         = DVRVolume::create();
    DVRAppearancePtr     app         = DVRAppearance::create(); 
    DVRVolumeTexturePtr  tex         = DVRVolumeTexture::create();

    beginEditCP(tex);
    tex->setImage(datImage);
    endEditCP(tex);

    // Attach the volume texture to the appearance
    beginEditCP(app, Node::AttachmentsFieldMask);
    app->addAttachment(tex);
    endEditCP  (app, Node::AttachmentsFieldMask);

    // Assign the appearance to the volume core
    beginEditCP(vol);
    vol->setAppearance(app);
    vol->setShader(DVRSimpleShader::create());
    endEditCP(vol);

    // Create a node for the volume core
    NodePtr newGeom = Node::create();
    beginEditCP(newGeom);
    newGeom->setCore(vol);
    endEditCP(newGeom);
    
    return newGeom;
}
// Create a volume rendering node with all desired attachments
NodePtr makeVolume( const char * datFile)
{
    DVRVolumePtr         vol         = DVRVolume::create();
    DVRAppearancePtr     app         = DVRAppearance::create();
    DVRVolumeTexturePtr  tex         = DVRVolumeTexture::create();
    DVRLookupTablePtr    lut         = DVRLookupTable::create();

    volume = vol;

    // Load the 3D-image and store it in the volume texture attachment
    ImagePtr datImage = Image::create();
    if (false == datImage->read(datFile)) {
        SLOG << "File: " << datFile << " not found" << std::endl;
        exit (-1);
    }
    beginEditCP(tex);
    tex->setImage(datImage);
    tex->setFileName(datFile);
    endEditCP(tex);

    //!! FIXME - Initialize the lookup table
    //!! This should not be neccessary if the OpenSG reader works correctly
    beginEditCP(lut, DVRLookupTable::TouchedFieldMask);
    lut->setTouched(true);
    endEditCP(lut, DVRLookupTable::TouchedFieldMask);

    // Initialize the lookup table
    beginEditCP(lut, DVRLookupTable::DataFieldMask);
    for (int i = 0; i < 1024; i++)
        lut->getData()[i] = lutData[i];
    endEditCP(lut, DVRLookupTable::DataFieldMask);

    // Attach the volume texture and lookup table to the appearance
    beginEditCP(app, Node::AttachmentsFieldMask);
    app->addAttachment(tex);
    app->addAttachment(lut);
    endEditCP  (app, Node::AttachmentsFieldMask);

    // Create a shader
    shader = DVRSimpleLUTShader::create();

    // Assign the appearance and shader to the volume core
    beginEditCP(vol);
    vol->setFileName(datFile);
    vol->setAppearance(app);
    vol->setShader(shader);
    endEditCP(vol);

    // Create a node for the volume core
    NodePtr newGeom = Node::create();
    beginEditCP(newGeom);
    newGeom->setCore(vol);
    endEditCP(newGeom);

    return newGeom;
}
// Create a volume rendering node with all desired attachments
NodePtr makeVolume( const char * datFile)
{  
    DVRVolumePtr         vol         = DVRVolume::create();
    DVRAppearancePtr     app         = DVRAppearance::create(); 
    DVRVolumeTexturePtr  tex         = DVRVolumeTexture::create();

    // Load the 3D-image and store it in the volume texture attachment
    ImagePtr datImage = Image::create();
    if (false == datImage->read(datFile)) {
        SLOG << "File: " << datFile << " not found" << std::endl;
	exit (-1);
    }
    beginEditCP(tex);
    tex->setImage(datImage);
    tex->setFileName(datFile);
    endEditCP(tex);

    // Attach the volume texture to the appearance
    beginEditCP(app, Node::AttachmentsFieldMask);
    app->addAttachment(tex);
    endEditCP  (app, Node::AttachmentsFieldMask);

    // Assign the appearance to the volume core
    beginEditCP(vol);
    vol->setFileName(datFile);
    vol->setAppearance(app);
    vol->setShader(DVRSimpleShader::create());
    endEditCP(vol);

    // Create a node for the volume core
    NodePtr newGeom = Node::create();
    beginEditCP(newGeom);
    newGeom->setCore(vol);
    endEditCP(newGeom);
    
    return newGeom;
}