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 }
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; }
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); }
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")); }
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(); } }
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); }
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(); }
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; }