void ImageRAM::update(bool editable) { colorLayersRAM_.clear(); depthLayerRAM_ = nullptr; pickingLayerRAM_ = nullptr; if (editable) { auto owner = static_cast<Image*>(this->getOwner()); for (size_t i = 0; i < owner->getNumberOfColorLayers(); ++i) { colorLayersRAM_.push_back( owner->getColorLayer(i)->getEditableRepresentation<LayerRAM>()); } if (auto depthLayer = owner->getDepthLayer()) { depthLayerRAM_ = depthLayer->getEditableRepresentation<LayerRAM>(); } if (auto pickingLayer = owner->getPickingLayer()) { pickingLayerRAM_ = pickingLayer->getEditableRepresentation<LayerRAM>(); } } else { auto owner = static_cast<const Image*>(this->getOwner()); for (size_t i = 0; i < owner->getNumberOfColorLayers(); ++i) { colorLayersRAM_.push_back( const_cast<LayerRAM*>(owner->getColorLayer(i)->getRepresentation<LayerRAM>())); } if (auto depthLayer = owner->getDepthLayer()) { depthLayerRAM_ = const_cast<LayerRAM*>(depthLayer->getRepresentation<LayerRAM>()); } if (auto pickingLayer = owner->getPickingLayer()) { pickingLayerRAM_ = const_cast<LayerRAM*>(pickingLayer->getRepresentation<LayerRAM>()); } } }
void ImageDisk::update(bool editable) { auto owner = static_cast<Image*>(this->getOwner()); if (editable) { for (size_t i=0; i<owner->getNumberOfColorLayers(); ++i) owner->getColorLayer(i)->getEditableRepresentation<LayerDisk>(); Layer* depthLayer = owner->getDepthLayer(); if (depthLayer) depthLayer->getEditableRepresentation<LayerDisk>(); Layer* pickingLayer = owner->getPickingLayer(); if (pickingLayer) pickingLayer->getEditableRepresentation<LayerDisk>(); } else { for (size_t i=0; i<owner->getNumberOfColorLayers(); ++i) owner->getColorLayer(i)->getRepresentation<LayerDisk>(); Layer* depthLayer = owner->getDepthLayer(); if (depthLayer) depthLayer->getRepresentation<LayerDisk>(); Layer* pickingLayer = owner->getPickingLayer(); if (pickingLayer) pickingLayer->getRepresentation<LayerDisk>(); } }
void ImageCL::update(bool editable) { // TODO: Convert more then just first color layer layerCL_ = nullptr; auto owner = static_cast<Image*>(this->getOwner()); if (editable) { layerCL_ = owner->getColorLayer()->getEditableRepresentation<LayerCL>(); } else { layerCL_ = const_cast<LayerCL*>(owner->getColorLayer()->getRepresentation<LayerCL>()); } if (layerCL_->getDataFormat() != owner->getDataFormat()) { owner->getColorLayer()->setDataFormat(layerCL_->getDataFormat()); owner->getColorLayer()->setDimensions(layerCL_->getDimensions()); } }
void ImageExport::processExport(){ exportQueued_ = false; auto image = imagePort_.getData(); if (image && !imageFile_.get().empty()) { const Layer* layer = image->getColorLayer(); if (layer){ std::string fileExtension = filesystem::getFileExtension(imageFile_.get()); auto writer = DataWriterFactory::getPtr()->getWriterForTypeAndExtension<Layer>(fileExtension); if (writer) { try { writer->setOverwrite(overwrite_.get()); writer->writeData(layer, imageFile_.get()); LogInfo("Image color layer exported to disk: " << imageFile_.get()); } catch (DataWriterException const& e) { util::log(e.getContext(), e.getMessage(), LogLevel::Error); } } else { LogError("Error: Could not find a writer for the specified extension and data type"); } } else { LogError("Error: Could not find color layer to write out"); } } else if (imageFile_.get().empty()) { LogWarn("Error: Please specify a file to write to"); } else if (!image) { LogWarn("Error: Please connect an image to export"); } }
void ImageGL::update(bool editable) { colorLayersGL_.clear(); depthLayerGL_ = nullptr; pickingLayerGL_ = nullptr; if (editable) { auto owner = static_cast<Image*>(this->getOwner()); for (size_t i = 0; i < owner->getNumberOfColorLayers(); ++i) { colorLayersGL_.push_back(owner->getColorLayer(i)->getEditableRepresentation<LayerGL>()); } Layer* depthLayer = owner->getDepthLayer(); if (depthLayer) { depthLayerGL_ = depthLayer->getEditableRepresentation<LayerGL>(); } Layer* pickingLayer = owner->getPickingLayer(); if (pickingLayer) { pickingLayerGL_ = pickingLayer->getEditableRepresentation<LayerGL>(); } } else { auto owner = static_cast<const Image*>(this->getOwner()); for (size_t i = 0; i < owner->getNumberOfColorLayers(); ++i) { colorLayersGL_.push_back( const_cast<LayerGL*>(owner->getColorLayer(i)->getRepresentation<LayerGL>())); } const Layer* depthLayer = owner->getDepthLayer(); if (depthLayer) { depthLayerGL_ = const_cast<LayerGL*>(depthLayer->getRepresentation<LayerGL>()); } const Layer* pickingLayer = owner->getPickingLayer(); if (pickingLayer) { pickingLayerGL_ = const_cast<LayerGL*>(pickingLayer->getRepresentation<LayerGL>()); } } // Attach all targets reAttachAllLayers(ImageType::AllLayers); }
void RBFVectorFieldGenerator2D::process() { if (samples_.size() != static_cast<size_t>(seeds_.get())) { createSamples(); } Eigen::MatrixXd A(seeds_.get(), seeds_.get()); Eigen::VectorXd bx(seeds_.get()), by(seeds_.get()); Eigen::VectorXd xx(seeds_.get()), xy(seeds_.get()); int row = 0; for (auto &a : samples_) { int col = 0; for (auto &b : samples_) { auto r = glm::distance(a.first, b.first); A(row, col++) = shape_.get() + gaussian_.evaluate(r); } bx(row) = a.second.x; by(row++) = a.second.y; } auto solverX = A.llt(); auto solverY = A.llt(); xx = solverX.solve(bx); xy = solverY.solve(by); auto img = std::make_shared<Image>(size_.get(), DataVec4Float32::get()); vec4 *data = static_cast<vec4 *>(img->getColorLayer()->getEditableRepresentation<LayerRAM>()->getData()); int i = 0; for (int y = 0; y < size_.get().y; y++) { for (int x = 0; x < size_.get().x; x++) { dvec2 p(x, y); p /= size_.get(); p *= 2; p -= 1; vec3 v(0, 0, 0); int s = 0; for (; s < seeds_.get(); s++) { double r = glm::distance(p, samples_[s].first); auto w = gaussian_.evaluate(r); v.x += static_cast<float>(xx(s) * w); v.y += static_cast<float>(xy(s) * w); } data[i++] = vec4(v, 1.0f); } } vectorField_.setData(img); }
void ImageGL::updateExistingLayers() const { auto owner = static_cast<const Image*>(this->getOwner()); for (size_t i = 0; i < owner->getNumberOfColorLayers(); ++i) { owner->getColorLayer(i)->getRepresentation<LayerGL>(); } const Layer* depthLayer = owner->getDepthLayer(); if (depthLayer) depthLayer->getRepresentation<LayerGL>(); const Layer* pickingLayer = owner->getPickingLayer(); if (pickingLayer) pickingLayer->getRepresentation<LayerGL>(); }
void HeightFieldMapper::process() { if (!inport_.isReady()) return; auto srcImg = inport_.getData(); if (!srcImg) { LogWarn("No valid input image given"); return; } // check the number of channels const DataFormatBase *format = srcImg->getDataFormat(); std::size_t numInputChannels = format->getComponents(); size2_t dim = srcImg->getDimensions(); Image *outImg = nullptr; // check format of output image if (!outImg || (outImg->getDataFormat()->getId() != DataFormatId::Float32)) { // replace with new floating point image Image *img = new Image(dim, DataFloat32::get()); outport_.setData(img); outImg = img; } else if (outImg->getDimensions() != dim) { // adjust dimensions of output image outImg->setDimensions(dim); } LayerRAM *dstLayer = outImg->getColorLayer(0)->getEditableRepresentation<LayerRAM>(); float *data = static_cast<float *>(dstLayer->getData()); // convert input image to float image const LayerRAM *srcLayer = srcImg->getColorLayer(0)->getRepresentation<LayerRAM>(); // special case: input image is already FLOAT32 with 1 channel if ((numInputChannels == 1) && (format->getId() == DataFormatId::Float32)) { const float *srcData = static_cast<const float *>(srcLayer->getData()); std::copy(srcData, srcData + dim.x * dim.y, data); } else { switch (numInputChannels) { case 2: for (unsigned int y = 0; y < dim.y; ++y) { for (unsigned int x = 0; x < dim.x; ++x) { data[y * dim.x + x] = static_cast<float>(srcLayer->getValueAsVec2Double(glm::uvec2(x, y)).r); } } break; case 3: for (unsigned int y = 0; y < dim.y; ++y) { for (unsigned int x = 0; x < dim.x; ++x) { data[y * dim.x + x] = static_cast<float>(srcLayer->getValueAsVec3Double(glm::uvec2(x, y)).r); } } break; case 4: for (unsigned int y = 0; y < dim.y; ++y) { for (unsigned int x = 0; x < dim.x; ++x) { data[y * dim.x + x] = static_cast<float>(srcLayer->getValueAsVec4Double(glm::uvec2(x, y)).r); } } break; case 1: default: for (unsigned int y = 0; y < dim.y; ++y) { for (unsigned int x = 0; x < dim.x; ++x) { data[y * dim.x + x] = static_cast<float>(srcLayer->getValueAsSingleDouble(glm::uvec2(x, y))); } } break; } } // rescale data set std::size_t numValues = dim.x * dim.y; // determine min/max values float minVal = *std::min_element(data, data + numValues); float maxVal = *std::max_element(data, data + numValues); switch (scalingModeProp_.get()) { case HeightFieldScaling::SeaLevel: { // scale heightfield based on sea level and min/max height float sealevel = seaLevel_.get(); float aboveSea = maxVal - sealevel; float belowSea = minVal - sealevel; float factor = maxHeight_.get() / std::max(aboveSea, std::abs(belowSea)); for (std::size_t i = 0; i < numValues; ++i) { data[i] = (data[i] - sealevel) * factor; } } break; case HeightFieldScaling::DataRange: { // scale data to [heightRange_.min : heightRange_.max] glm::vec2 range(heightRange_.get()); float factor = (range.y - range.x) / (maxVal - minVal); for (std::size_t i = 0; i < numValues; ++i) { data[i] = (data[i] - minVal) * factor + range.x; } } break; case HeightFieldScaling::FixedRange: default: { // scale data to [0:1] range float delta = 1.0f / (maxVal - minVal); for (std::size_t i = 0; i < numValues; ++i) { data[i] = (data[i] - minVal) * delta; } } break; } }
/* Algorithm as describe by: http://devmag.org.za/2009/05/03/poisson-disk-sampling/ */ void NoiseProcessor::poissonDisk(Image *img) { float minDist = size_.get().x; minDist /= poissonDotsAlongX_; //min pixel distance between samples auto minDist2 = minDist*minDist; size2_t gridSize = size2_t(1)+ size2_t(vec2(size_.get()) * (1.0f / minDist)); auto gridImg = util::make_unique<Image>(gridSize, DataVec2INT32::get()); auto grid = gridImg->getColorLayer()->getEditableRepresentation<LayerRAM>(); auto imgData = static_cast<float*>(img->getColorLayer()->getEditableRepresentation<LayerRAM>()->getData()); auto gridData = static_cast<glm::i32vec2*>(grid->getData()); util::IndexMapper2D imgIndex(size_.get()); util::IndexMapper2D gridIndex(gridSize); for (size_t i = 0; i < gridSize.x*gridSize.y; i++) { gridData[i] = glm::i32vec2(-2 * minDist); } std::uniform_int_distribution<int> rx(0, size_.get().x); std::uniform_int_distribution<int> ry(0, size_.get().y); std::uniform_real_distribution<float> rand(0, 1); std::vector<glm::i32vec2> processList; std::vector<glm::i32vec2> samplePoints; auto firstPoint = glm::i32vec2(rx(mt_), ry(mt_)); processList.push_back(firstPoint); samplePoints.push_back(firstPoint); auto toGrid = [minDist](glm::i32vec2 p)->glm::i32vec2 { return glm::i32vec2(vec2(p)/minDist); }; gridData[gridIndex(toGrid(firstPoint))] = firstPoint; int someNumber = 30; while (processList.size() != 0 && samplePoints.size() < static_cast<size_t>(poissonMaxPoints_)) { std::uniform_int_distribution<size_t> ri(0, processList.size()-1); auto i = ri(mt_); auto p = processList[i]; processList.erase(processList.begin() + i); for (int j = 0; j < someNumber; j++) { auto newPoint = generateRandomPointAround(p, minDist, rand, mt_); if (newPoint.x < 0) continue; if (newPoint.y < 0) continue; if (newPoint.x >= size_.get().x) continue; if (newPoint.y >= size_.get().y) continue; auto newGridPoint = toGrid(newPoint); bool neighbourhood = false; int startX = std::max(0, newGridPoint.x - 2); int startY = std::max(0, newGridPoint.y - 2); int endX = std::min(static_cast<int>(gridSize.x) - 1, newGridPoint.x + 2); int endY = std::min(static_cast<int>(gridSize.y) - 1, newGridPoint.y + 2); for (int x = startX; x <= endX && !neighbourhood; x++) { for (int y = startY; y <= endY && !neighbourhood; y++) { auto p2 = gridData[gridIndex(glm::i32vec2(x, y))]; auto dist = glm::distance2(vec2(newPoint), vec2(p2)); if (dist < minDist2) { neighbourhood = true; } } }//*/ if (!neighbourhood) { processList.push_back(newPoint); samplePoints.push_back(newPoint); auto idx = gridIndex(newGridPoint); gridData[idx] = newPoint; imgData[imgIndex(newPoint)] = 1; } } } }