void VolumeMaxCLProcessor::executeVolumeOperation(const Volume* volume,
                                                  const VolumeCLBase* volumeCL,
                                                  VolumeCLBase* volumeOutCL, const size3_t& outDim,
                                                  const size3_t& globalWorkGroupSize,
                                                  const size3_t& localWorkgroupSize) {
    cl::Event events[2];
    try {
        BufferCL* tmpVolumeCL;
        int argIndex = 0;
        kernel_->setArg(argIndex++, *volumeCL);
        kernel_->setArg(argIndex++,
                        *(volumeCL->getVolumeStruct(volume)
                              .getRepresentation<BufferCL>()));  // Scaling for 12-bit data
        if (supportsVolumeWrite_) {
            kernel_->setArg(argIndex++, *volumeOutCL);
        } else {
            size_t outDimFlattened = outDim.x * outDim.y * outDim.z;
            if (tmpVolume_ == nullptr || tmpVolume_->getSize() != outDimFlattened) {
                delete tmpVolume_;
                tmpVolume_ = new Buffer<unsigned char>(outDimFlattened);
            }
            tmpVolumeCL = tmpVolume_->getEditableRepresentation<BufferCL>();
            kernel_->setArg(argIndex++, *tmpVolumeCL);
        }
        kernel_->setArg(argIndex++, ivec4(outDim, 0));
        kernel_->setArg(argIndex++, ivec4(volumeRegionSize_.get()));

        OpenCL::getPtr()->getQueue().enqueueNDRangeKernel(
            *kernel_, cl::NullRange, globalWorkGroupSize, localWorkgroupSize, nullptr, &events[0]);

        if (!supportsVolumeWrite_) {
            std::vector<cl::Event> waitFor(1, events[0]);
            OpenCL::getPtr()->getQueue().enqueueCopyBufferToImage(
                tmpVolumeCL->get(), volumeOutCL->getEditable(), 0, size3_t(0), size3_t(outDim),
                &waitFor, &events[1]);
        }
    } catch (cl::Error& err) {
        LogError(getCLErrorString(err));
    }

#if IVW_PROFILING
    try {
        if (supportsVolumeWrite_) {
            events[0].wait();
            LogInfo("Exec time: " << events[0].getElapsedTime() << " ms");
        } else {
            // Measure both computation and copy (only need to wait for copy)
            events[1].wait();
            LogInfo("Exec time (computation, copy): "
                    << events[0].getElapsedTime() << " + " << events[1].getElapsedTime() << " = "
                    << events[0].getElapsedTime() + events[1].getElapsedTime() << " ms");
        }
    } catch (cl::Error& err) {
        LogError(getCLErrorString(err));
    }
#endif
}
Exemple #2
0
void LightVolumeGL::volumeSizeOptionChanged() {
    if (inport_.hasData()) {
        if ((inport_.getData()->getDimensions()/size3_t(volumeSizeOption_.get())) != volumeDimOut_) {
            internalVolumesInvalid_ = true;
        }
    }
}
const HistogramContainer* TransferFunctionEditorView::getNormalizedHistograms() {
    if (volumeInport_ && volumeInport_->hasData()) {
        const VolumeRAM* volumeRAM = volumeInport_->getData()->getRepresentation<VolumeRAM>();

        if (volumeRAM) {
            if (volumeRAM->hasHistograms()) return volumeRAM->getHistograms(2048, size3_t(1));

            else if (!histogramTheadWorking_) {
                histogramTheadWorking_ = true;
                workerThread_ = new QThread();
                worker_ = new HistogramWorkerQt(volumeRAM, 2048);
                worker_->moveToThread(workerThread_);
                connect(workerThread_, SIGNAL(started()), worker_, SLOT(process()));
                connect(worker_, SIGNAL(finished()), workerThread_, SLOT(quit()));
                connect(workerThread_, SIGNAL(finished()), this, SLOT(histogramThreadFinished()));

                // clean up objects
                connect(worker_, SIGNAL(finished()), worker_, SLOT(deleteLater()));
                connect(workerThread_, SIGNAL(finished()), workerThread_, SLOT(deleteLater()));
                workerThread_->start();
            }
        }
    }

    return nullptr;
}
Exemple #4
0
VolumeSubset::VolumeSubset() : Processor()
      , inport_("volume.inport")
      , outport_("volume.outport")
      , enabled_("enabled", "Enable Operation", true)
      , adjustBasisAndOffset_("adjustBasisAndOffset", "Adjust Basis and Offset", true)
      , rangeX_("rangeX", "X Slices", 0, 256, 0, 256, 1, 1)
      , rangeY_("rangeY", "Y Slices", 0, 256, 0, 256, 1, 1)
      , rangeZ_("rangeZ", "Z Slices", 0, 256, 0, 256, 1, 1)
{
    addPort(inport_);
    addPort(outport_);
    addProperty(enabled_);
    addProperty(adjustBasisAndOffset_);
    addProperty(rangeX_);
    addProperty(rangeY_);
    addProperty(rangeZ_);
    dims_ = size3_t(1,1,1);

    // Since the ranges depend on the input volume dimensions, we make sure to always
    // serialize them so we can do a proper renormalization when we load new data.
    rangeX_.setSerializationMode(PropertySerializationMode::ALL);
    rangeY_.setSerializationMode(PropertySerializationMode::ALL);
    rangeZ_.setSerializationMode(PropertySerializationMode::ALL);

    inport_.onChange(this, &VolumeSubset::onVolumeChange);
}
Exemple #5
0
void VolumeSubset::process() {
    if (enabled_.get()) {
        const VolumeRAM* vol = inport_.getData()->getRepresentation<VolumeRAM>();
        size3_t dim = size3_t(static_cast<unsigned int>(rangeX_.get().y),
                          static_cast<unsigned int>(rangeY_.get().y),
                          static_cast<unsigned int>(rangeZ_.get().y));
        size3_t offset = size3_t(static_cast<unsigned int>(rangeX_.get().x),
                             static_cast<unsigned int>(rangeY_.get().x),
                             static_cast<unsigned int>(rangeZ_.get().x));
        dim -= offset;

        if (dim == dims_)
            outport_.setData(inport_.getData());
        else {
            Volume* volume = new Volume(VolumeRAMSubSet::apply(vol, dim, offset));
            // pass meta data on
            volume->copyMetaDataFrom(*inport_.getData());
            volume->dataMap_ = inport_.getData()->dataMap_;

            if (adjustBasisAndOffset_.get()) {
                vec3 volOffset = inport_.getData()->getOffset();
                mat3 volBasis = inport_.getData()->getBasis();

                const vec3 newOffset =
                    volOffset + volBasis * (static_cast<vec3>(offset) / static_cast<vec3>(dims_));

                mat3 newBasis = volBasis;
                vec3 dimRatio = (static_cast<vec3>(dim) / static_cast<vec3>(dims_));
                newBasis[0] *= dimRatio[0];
                newBasis[1] *= dimRatio[1];
                newBasis[2] *= dimRatio[2];

                volume->setBasis(newBasis);
                volume->setOffset(newOffset);

            } else {
                // copy basis and offset
                volume->setModelMatrix(inport_.getData()->getModelMatrix());
            }
            outport_.setData(volume);
        }
    } else {
        outport_.setData(inport_.getData());
    }
}
IvfVolumeReader::IvfVolumeReader()
    : DataReaderType<Volume>()
    , rawFile_("")
    , filePos_(0)
    , littleEndian_(true)
    , dimensions_(size3_t(0))
    , format_(nullptr) {
    addExtension(FileExtension("ivf", "Inviwo ivf file format"));
}
Exemple #7
0
void CubeProxyGeometry::onVolumeChange() {
    // Update to the new dimensions.
    auto dims = inport_.getData()->getDimensions();
    if (dims != size3_t(clipX_.getRangeMax(), clipY_.getRangeMax(), clipZ_.getRangeMax())) {
        NetworkLock lock(this);

        clipX_.setRangeNormalized(ivec2(0, dims.x));
        clipY_.setRangeNormalized(ivec2(0, dims.y));
        clipZ_.setRangeNormalized(ivec2(0, dims.z));

        // set the new dimensions to default if we were to press reset
        clipX_.setCurrentStateAsDefault();
        clipY_.setCurrentStateAsDefault();
        clipZ_.setCurrentStateAsDefault();
    }

}
Exemple #8
0
    void* dispatch(void* dst, const char* filePath, size3_t& dimensions, DataFormatId& formatId,
                   const DataFormatBase* dataFormat) {
        CImg<typename T::primitive> img(filePath);

        size_t components = static_cast<size_t>(img.spectrum());
        dimensions = size3_t(img.width(), img.height(), img.depth());

        const DataFormatBase* loadedDataFormat = DataFormatBase::get(
            dataFormat->getNumericType(), components, sizeof(typename T::primitive) * 8);
        if (loadedDataFormat)
            formatId = loadedDataFormat->getId();
        else
            throw Exception("CImgLoadVolumeDispatcher, could not find proper data type");

        // Image is up-side-down
        img.mirror('y');

        return CImgToVoidConvert<typename T::primitive>::convert(dst, &img);
    }
Exemple #9
0
size3_t getGlobalWorkGroupSize(size3_t nItems, glm::size3_t localWorkGroupSize)
{
    return localWorkGroupSize*size3_t(glm::ceil(vec3(nItems) / vec3(localWorkGroupSize)));
}
void HistogramWorkerQt::process() {
    volumeRAM_->calculateHistograms(numBins_, size3_t(1), stop);
    emit finished();
}
Exemple #11
0
std::shared_ptr<Volume> curlVolume(std::shared_ptr<const Volume> volume) {
    auto newVolume = std::make_shared<Volume>(volume->getDimensions(), DataVec3Float32::get());
    newVolume->setModelMatrix(volume->getModelMatrix());
    newVolume->setWorldMatrix(volume->getWorldMatrix());

    newVolume->dataMap_ = volume->dataMap_;

    auto m = newVolume->getCoordinateTransformer().getDataToWorldMatrix();

    auto a = m * vec4(0, 0, 0, 1);
    auto b = m * vec4(1.0f / vec3(volume->getDimensions() - size3_t(1)), 1);
    auto spacing = b - a;

    vec3 ox = vec3(spacing.x, 0, 0);
    vec3 oy = vec3(0, spacing.y, 0);
    vec3 oz = vec3(0, 0, spacing.z);

    VolumeDoubleSampler<4> sampler(volume);
    auto worldSpace = VolumeDoubleSampler<3>::Space::World;

    util::IndexMapper3D index(volume->getDimensions());
    auto data = static_cast<vec3*>(newVolume->getEditableRepresentation<VolumeRAM>()->getData());

            float minV = std::numeric_limits<float>::max(), maxV = std::numeric_limits<float>::lowest();

    std::function<void(const size3_t&)> func = [&](const size3_t& pos) {
        vec3 world = (m * vec4(vec3(pos) / vec3(volume->getDimensions() - size3_t(1)), 1)).xyz();

        auto Fx =
            (sampler.sample(world + ox, worldSpace) - sampler.sample(world - ox, worldSpace)) /
            (2.0 * spacing.x);
        auto Fy =
            (sampler.sample(world + oy, worldSpace) - sampler.sample(world - oy, worldSpace)) /
            (2.0 * spacing.y);
        auto Fz =
            (sampler.sample(world + oz, worldSpace) - sampler.sample(world - oz, worldSpace)) /
            (2.0 * spacing.z);

        vec3 c;
        c.x = static_cast<float>(Fy.z - Fz.y);
        c.y = static_cast<float>(Fz.x - Fx.z);
        c.z = static_cast<float>(Fx.y - Fy.x);

                minV = std::min(minV, c.x);
                minV = std::min(minV, c.y);
                minV = std::min(minV, c.z);
                maxV = std::max(maxV, c.x);
                maxV = std::max(maxV, c.y);
                maxV = std::max(maxV, c.z);

        data[index(pos)] = c;
    };

    util::forEachVoxel(*volume->getRepresentation<VolumeRAM>(), func);

            auto range = std::max(std::abs(minV), std::abs(maxV));
            newVolume->dataMap_.dataRange = dvec2(-range, range);
            newVolume->dataMap_.valueRange = dvec2(minV, maxV);


    return newVolume;
}