Commit a05aca93 authored by Jørgen Lind's avatar Jørgen Lind
Browse files

Simplify Format resolution in SimplesNoiseKernel

parent 0c49c008
#include <OpenVDS/OpenVDS.h>
#include <OpenVDS/VolumeDataLayoutDescriptor.h>
#include <OpenVDS/VolumeDataAxisDescriptor.h>
#include <OpenVDS/VolumeDataChannelDescriptor.h>
#include <OpenVDS/KnownMetadata.h>
#include <OpenVDS/GlobalMetadataCommon.h>
#include <OpenVDS/VolumeDataLayout.h>
#include <OpenVDS/VolumeDataAccess.h>
#include <VDS/SimplexNoiseKernel.h>
#include <random>
template<typename T>
void getRangeForFormat1(float &min, float &max)
{
min = std::numeric_limits<T>::min();
max = std::numeric_limits<T>::max();
}
template<>
void getRangeForFormat1<float>(float &min, float &max)
{
min = -1.f;
max = 1.f;
}
template<>
void getRangeForFormat1<double>(float &min, float &max)
{
min = -1.f;
max = 1.f;
}
void getRangeForFormat(OpenVDS::VolumeDataChannelDescriptor::Format format, float &min, float &max)
{
switch (format)
{
case OpenVDS::VolumeDataChannelDescriptor::Format_U8: getRangeForFormat1<uint8_t>(min, max); break;
case OpenVDS::VolumeDataChannelDescriptor::Format_U16: getRangeForFormat1<uint16_t>(min, max); break;
case OpenVDS::VolumeDataChannelDescriptor::Format_R32: getRangeForFormat1<float>(min, max); break;
case OpenVDS::VolumeDataChannelDescriptor::Format_U32: getRangeForFormat1<uint32_t>(min, max); break;
case OpenVDS::VolumeDataChannelDescriptor::Format_R64: getRangeForFormat1<double>(min, max); break;
case OpenVDS::VolumeDataChannelDescriptor::Format_U64: getRangeForFormat1<uint64_t>(min, max); break;
case OpenVDS::VolumeDataChannelDescriptor::Format_1Bit:
case OpenVDS::VolumeDataChannelDescriptor::Format_Any: break;
}
}
static OpenVDS::VDS *generateSimpleInMemory3DVDS(int32_t samplesX = 100, int32_t samplesY = 100, int32_t samplesZ = 100, OpenVDS::VolumeDataChannelDescriptor::Format format = OpenVDS::VolumeDataChannelDescriptor::Format_R32)
{
auto brickSize = OpenVDS::VolumeDataLayoutDescriptor::BrickSize_32;
int negativeMargin = 4;
int positiveMargin = 4;
int brickSize2DMultiplier = 4;
auto lodLevels = OpenVDS::VolumeDataLayoutDescriptor::LODLevels_None;
auto layoutOptions = OpenVDS::VolumeDataLayoutDescriptor::Options_None;
OpenVDS::VolumeDataLayoutDescriptor layoutDescriptor(brickSize, negativeMargin, positiveMargin, brickSize2DMultiplier, lodLevels, layoutOptions);
std::vector<OpenVDS::VolumeDataAxisDescriptor> axisDescriptors;
axisDescriptors.emplace_back(samplesX, KNOWNMETADATA_SURVEYCOORDINATE_INLINECROSSLINE_AXISNAME_SAMPLE, "ms", 0.0f, 4.f);
axisDescriptors.emplace_back(samplesY, KNOWNMETADATA_SURVEYCOORDINATE_INLINECROSSLINE_AXISNAME_CROSSLINE, "", 1932.f, 2536.f);
axisDescriptors.emplace_back(samplesZ, KNOWNMETADATA_SURVEYCOORDINATE_INLINECROSSLINE_AXISNAME_INLINE, "", 9985.f, 10369.f);
std::vector<OpenVDS::VolumeDataChannelDescriptor> channelDescriptors;
float rangeMin, rangeMax;
getRangeForFormat(format, rangeMin, rangeMax);
channelDescriptors.emplace_back(format, OpenVDS::VolumeDataChannelDescriptor::Components_1, AMPLITUDE_ATTRIBUTE_NAME, "", rangeMin, rangeMax);
OpenVDS::InMemoryOpenOptions options;
OpenVDS::MetadataContainer metadataContainer;
OpenVDS::Error error;
return OpenVDS::Create(options, layoutDescriptor, axisDescriptors, channelDescriptors, metadataContainer, error);
}
static void fill3DVDSWithNoise(OpenVDS::VDS *vds, int32_t channel = 0, const OpenVDS::FloatVector3 &frequency = OpenVDS::FloatVector3(0.6f, 2.f, 4.f))
{
OpenVDS::VolumeDataLayout *layout = OpenVDS::GetLayout(vds);
//ASSERT_TRUE(layout);
OpenVDS::VolumeDataAccessManager *accessManager = OpenVDS::GetAccessManager(vds);
//ASSERT_TRUE(accessManager);
OpenVDS::VolumeDataPageAccessor *pageAccessor = accessManager->CreateVolumeDataPageAccessor(layout, OpenVDS::Dimensions_012, channel, 0, 100, OpenVDS::VolumeDataAccessManager::AccessMode_Create);
//ASSERT_TRUE(pageAccessor);
int32_t chunkCount = int32_t(pageAccessor->GetChunkCount());
OpenVDS::VolumeDataChannelDescriptor::Format format = layout->GetChannelFormat(channel);
for (int i = 0; i < chunkCount; i++)
{
OpenVDS::VolumeDataPage *page = pageAccessor->CreatePage(i);
OpenVDS::VolumeIndexer3D outputIndexer(page, 0, 0, OpenVDS::Dimensions_012, layout);
int pitch[OpenVDS::Dimensionality_Max];
void *buffer = page->GetWritableBuffer(pitch);
OpenVDS::CalculateNoise3D(buffer, format, &outputIndexer, frequency, 0.021f, 0.f, true, 345);
page->Release();
}
pageAccessor->Commit();
pageAccessor->SetMaxPages(0);
accessManager->FlushUploadQueue();
accessManager->DestroyVolumeDataPageAccessor(pageAccessor);
}
static void fill3DVDSWithBitNoise(OpenVDS::VDS *vds, int32_t channel = 0)
{
OpenVDS::VolumeDataLayout *layout = OpenVDS::GetLayout(vds);
//ASSERT_TRUE(layout);
OpenVDS::VolumeDataAccessManager *accessManager = OpenVDS::GetAccessManager(vds);
//ASSERT_TRUE(accessManager);
OpenVDS::VolumeDataPageAccessor *pageAccessor = accessManager->CreateVolumeDataPageAccessor(layout, OpenVDS::Dimensions_012, channel, 0, 100, OpenVDS::VolumeDataAccessManager::AccessMode_Create);
//ASSERT_TRUE(pageAccessor);
int32_t chunkCount = int32_t(pageAccessor->GetChunkCount());
std::mt19937 gen(123);
std::bernoulli_distribution dist(0.8);
for (int i = 0; i < chunkCount; i++)
{
OpenVDS::VolumeDataPage *page = pageAccessor->CreatePage(i);
OpenVDS::VolumeIndexer3D outputIndexer(page, 0, 0, OpenVDS::Dimensions_012, layout);
int pitch[OpenVDS::Dimensionality_Max];
uint8_t *buffer = static_cast<uint8_t *>(page->GetWritableBuffer(pitch));
int32_t min[OpenVDS::Dimensionality_Max];
int32_t max[OpenVDS::Dimensionality_Max];
page->GetMinMax(min, max);
int32_t size[OpenVDS::Dimensionality_Max];
for (int i = 0; i < OpenVDS::Dimensionality_Max; i++)
size[i] = max[i] - min[i];
for (int z = 0; z < size[2]; z++)
{
for (int y = 0; y < size[1]; y++)
{
for(int x = 0; x < size[0]; x++)
{
int32_t byteIndex = z * pitch[2] + y * pitch[1] + (x / 8);
int32_t bitIndex = z * size[2] * size[1] * size[0] + y * size[1] * size[0] + x;
uint8_t byte = buffer[byteIndex];
bool value = dist(gen);
if (value)
byte |= uint8_t(1) << (bitIndex % 8);
buffer[byteIndex] = byte;
}
}
}
page->Release();
}
pageAccessor->Commit();
pageAccessor->SetMaxPages(0);
accessManager->FlushUploadQueue();
accessManager->DestroyVolumeDataPageAccessor(pageAccessor);
}
......@@ -135,7 +135,7 @@ int main(int argc, char **argv)
if (generate_noise)
{
handle.reset(generateSimpleInMemory3DVDS(60,60,60, OpenVDS::VolumeDataChannelDescriptor::Format_R32));
handle.reset(generateSimpleInMemory3DVDS(60,60,60, OpenVDS::VolumeDataChannelDescriptor::Format_U8));
if (handle)
fill3DVDSWithNoise(handle.get());
}
......
......@@ -134,9 +134,36 @@ float SimplexNoise(float *position, unsigned int randomSeed)
return 0.5f + noise * 5.0f / amplitudeSum;
}
template<bool useNoValue, template<typename, bool> typename T, typename ... Args>
static void GenericDispatcher_1(VolumeDataChannelDescriptor::Format format, Args ... args)
{
switch(format)
{
case VolumeDataChannelDescriptor::Format_1Bit:T<bool, useNoValue>::Do(args...); break;
case VolumeDataChannelDescriptor::Format_U8: T<uint8_t, useNoValue>::Do(args...); break;
case VolumeDataChannelDescriptor::Format_U16: T<uint16_t, useNoValue>::Do(args...); break;
case VolumeDataChannelDescriptor::Format_R32: T<float, useNoValue>::Do(args...); break;
case VolumeDataChannelDescriptor::Format_U32: T<uint32_t, useNoValue>::Do(args...); break;
case VolumeDataChannelDescriptor::Format_R64: T<double, useNoValue>::Do(args...); break;
case VolumeDataChannelDescriptor::Format_U64: T<uint64_t, useNoValue>::Do(args...); break;
}
}
template<template<typename, bool> typename T, typename ... Args>
static void GenericDispatcher(bool useNoValue, VolumeDataChannelDescriptor::Format format, Args ... args)
{
if (useNoValue)
GenericDispatcher_1<true, T, Args...>(format, args...);
else
GenericDispatcher_1<false, T, Args...>(format, args...);
};
template <typename T, bool useNoValue>
void Noise2DKernel(T* output, VolumeIndexer2D const &outputIndexer2D, FloatVector2 const &frequency, float threshold, float noValue, unsigned int random)
struct Noise2DKernel
{
static void Do(void * outputVoid, VolumeIndexer2D const &outputIndexer2D, FloatVector2 const &frequency, float threshold, float noValue, unsigned int random)
{
T *output = static_cast<T *>(outputVoid);
IntVector<2> numSamples;
IntVector<2> localOutIndex;
......@@ -170,38 +197,19 @@ void Noise2DKernel(T* output, VolumeIndexer2D const &outputIndexer2D, FloatVecto
output[outputIndexer2D.LocalIndexToDataIndex(localOutIndex)] = converter.ConvertValue(value < threshold ? noValue : (value * valueRangeScale + outputIndexer2D.valueRangeMin));
}
}
};
static void CalculateNoise2D(void* output, VolumeDataChannelDescriptor::Format eFormat, VolumeIndexer2D *pOutputIndexer, FloatVector2 frequency, float threshold, float noValue, bool useNoValue, unsigned int random)
static void CalculateNoise2D(void* output, VolumeDataChannelDescriptor::Format format, VolumeIndexer2D *outputIndexer, FloatVector2 frequency, float threshold, float noValue, bool useNoValue, unsigned int random)
{
if (useNoValue)
{
switch(eFormat)
{
case VolumeDataChannelDescriptor::Format_U8: Noise2DKernel<uint8_t, true>((uint8_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U16: Noise2DKernel<uint16_t, true>((uint16_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R32: Noise2DKernel<float, true>((float *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U32: Noise2DKernel<uint32_t, true>((uint32_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R64: Noise2DKernel<double, true>((double *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U64: Noise2DKernel<uint64_t, true>((uint64_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
}
}
else
{
switch(eFormat)
{
case VolumeDataChannelDescriptor::Format_U8: Noise2DKernel<uint8_t, false>((uint8_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U16: Noise2DKernel<uint16_t, false>((uint16_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R32: Noise2DKernel<float, false>((float *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U32: Noise2DKernel<uint32_t, false>((uint32_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R64: Noise2DKernel<double, false>((double *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U64: Noise2DKernel<uint64_t, false>((uint64_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
}
}
GenericDispatcher<Noise2DKernel>(useNoValue, format, output, *outputIndexer, frequency, threshold, noValue, random);
}
template <typename T, bool useNoValue>
void Noise3DKernel(T* output, VolumeIndexer3D const &outputIndexer3D, FloatVector3 const &frequency, float threshold, float noValue, unsigned int random)
struct Noise3DKernel
{
static void Do(void* outputVoid, VolumeIndexer3D const &outputIndexer3D, FloatVector3 const &frequency, float threshold, float noValue, unsigned int random)
{
T *output = static_cast<T*>(outputVoid);
IntVector<3> numSamples;
IntVector<3> localOutIndex;
......@@ -238,38 +246,19 @@ void Noise3DKernel(T* output, VolumeIndexer3D const &outputIndexer3D, FloatVecto
output[outputIndexer3D.LocalIndexToDataIndex(localOutIndex)] = converter.ConvertValue(value < threshold ? noValue : (value * valueRangeScale + outputIndexer3D.valueRangeMin));
}
}
};
static void CalculateNoise3D(void* output, VolumeDataChannelDescriptor::Format eFormat, VolumeIndexer3D *pOutputIndexer, FloatVector3 frequency, float threshold, float noValue, bool useNoValue, unsigned int random)
static void CalculateNoise3D(void* output, VolumeDataChannelDescriptor::Format format, VolumeIndexer3D *outputIndexer, FloatVector3 frequency, float threshold, float noValue, bool useNoValue, unsigned int random)
{
if (useNoValue)
{
switch(eFormat)
{
case VolumeDataChannelDescriptor::Format_U8: Noise3DKernel<uint8_t, true>((uint8_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U16: Noise3DKernel<uint16_t, true>((uint16_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R32: Noise3DKernel<float, true>((float *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U32: Noise3DKernel<uint32_t, true>((uint32_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R64: Noise3DKernel<double, true>((double *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U64: Noise3DKernel<uint64_t, true>((uint64_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
}
}
else
{
switch(eFormat)
{
case VolumeDataChannelDescriptor::Format_U8: Noise3DKernel<uint8_t, false>((uint8_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U16: Noise3DKernel<uint16_t, false>((uint16_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R32: Noise3DKernel<float, false>((float *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U32: Noise3DKernel<uint32_t, false>((uint32_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R64: Noise3DKernel<double, false>((double *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U64: Noise3DKernel<uint64_t, false>((uint64_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
}
}
GenericDispatcher<Noise3DKernel>(useNoValue, format, output, *outputIndexer, frequency, threshold, noValue, random);
}
template <typename T, bool useNoValue>
void Noise4DKernel(T* output, VolumeIndexer4D const &outputIndexer4D, FloatVector4 const &frequency, float threshold, float noValue, unsigned int random)
struct Noise4DKernel
{
static void Do(void* outputVoid, VolumeIndexer4D const &outputIndexer4D, FloatVector4 const &frequency, float threshold, float noValue, unsigned int random)
{
T *output = static_cast<T *>(outputVoid);
IntVector<4> numSamples;
for (int i=0; i<4; i++)
......@@ -306,32 +295,10 @@ void Noise4DKernel(T* output, VolumeIndexer4D const &outputIndexer4D, FloatVecto
output[outputIndexer4D.LocalIndexToDataIndex(localOutIndex)] = converter.ConvertValue(value < threshold ? noValue : (value * valueRangeScale + outputIndexer4D.valueRangeMin));
}
}
};
static void CalculateNoise4D(void* output, VolumeDataChannelDescriptor::Format eFormat, VolumeIndexer4D *pOutputIndexer, FloatVector4 frequency, float threshold, float noValue, bool useNoValue, unsigned int random)
static void CalculateNoise4D(void* output, VolumeDataChannelDescriptor::Format format, VolumeIndexer4D *outputIndexer, FloatVector4 frequency, float threshold, float noValue, bool useNoValue, unsigned int random)
{
if (useNoValue)
{
switch(eFormat)
{
case VolumeDataChannelDescriptor::Format_U8: Noise4DKernel<uint8_t, true>((uint8_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U16: Noise4DKernel<uint16_t, true>((uint16_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R32: Noise4DKernel<float, true>((float *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U32: Noise4DKernel<uint32_t, true>((uint32_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R64: Noise4DKernel<double, true>((double *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U64: Noise4DKernel<uint64_t, true>((uint64_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
}
}
else
{
switch(eFormat)
{
case VolumeDataChannelDescriptor::Format_U8: Noise4DKernel<uint8_t, false>((uint8_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U16: Noise4DKernel<uint16_t, false>((uint16_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R32: Noise4DKernel<float, false>((float *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U32: Noise4DKernel<uint32_t, false>((uint32_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_R64: Noise4DKernel<double, false>((double *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
case VolumeDataChannelDescriptor::Format_U64: Noise4DKernel<uint64_t, false>((uint64_t *)output, *pOutputIndexer, frequency, threshold, noValue, random); break;
}
}
GenericDispatcher<Noise4DKernel>(useNoValue, format, output, *outputIndexer, frequency, threshold, noValue, random);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment