Skip to content

Commit

Permalink
added: allow for defining a function for textureproperties
Browse files Browse the repository at this point in the history
this allows for a generic f(texture(X)) where f can be scalar or vector
valued.

ideally f would be a function of property name but
as we do not have a base class for f: R -> R^3 we have to use the
f: R^3 -> R^3 type for vector functions. for this reason, both
scalar and vectorial functions have to refer to the texture value as 'x'.
  • Loading branch information
akva2 committed Nov 12, 2021
1 parent d8d4d40 commit 107ecfe
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 20 deletions.
72 changes: 61 additions & 11 deletions src/Utility/TextureProperties.C
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "TextureProperties.h"
#include "IFEM.h"
#include "Functions.h"
#include "HDF5Reader.h"
#include "ProcessAdm.h"
#include "Utilities.h"
Expand All @@ -33,8 +34,11 @@ void TextureProperties::parse(const TiXmlElement* elem)
continue;
}

std::string textureFile;
std::string textureFile, function;
utl::getAttribute(child, "file", textureFile);
utl::getAttribute(child, "function", function);
int comp = 1;
utl::getAttribute(child,"comp",comp);

if (textureFile.find(".h5") != std::string::npos ||
textureFile.find(".hdf5") != std::string::npos) {
Expand Down Expand Up @@ -73,6 +77,17 @@ void TextureProperties::parse(const TiXmlElement* elem)
}

properties[prop].textureData.resize(nx,ny,nz);
if (!function.empty()) {
properties[prop].func_definition = function;
FunctionBase* func;
if (comp == 1)
func = utl::parseRealFunc(function.c_str());
else
func = utl::parseVecFunc(function.c_str());

properties[prop].function.reset(func);
}

const unsigned char* data = image;
for (int i = 1; i <= nx; ++i)
for (int j = 1; j <= ny; ++j)
Expand All @@ -89,10 +104,13 @@ void TextureProperties::parse(const TiXmlElement* elem)

void TextureProperties::printLog() const
{
for (const auto& prop : properties)
for (const auto& prop : properties) {
IFEM::cout << "\n\t\tProperty with name " << prop.first
<< " (min = " << prop.second.min
<< ", max = " << prop.second.max << ")";
if (!prop.second.func_definition.empty())
IFEM::cout << "\n\t\t\tfunction = " << prop.second.func_definition;
}
}


Expand All @@ -104,19 +122,33 @@ bool TextureProperties::getProperty(const std::string& name,
return false;

const Property& prop = it->second;
val = this->getValue(prop, X);

const Vec4* X4 = static_cast<const Vec4*>(&X);
if (!X4)
if (prop.function) {
Vec3 f;
f.x = val;
val = prop.function->getValue(f).front();
}

return true;
}

bool TextureProperties::getProperty(const std::string& name,
const Vec3& X, Vec3& val) const
{
auto it = properties.find(name);
if (it == properties.end())
return false;

int i = std::round(X4->u[0]*(prop.textureData.dim(1)-1));
int j = std::round(X4->u[1]*(prop.textureData.dim(2)-1));
int k = std::round(X4->u[2]*(prop.textureData.dim(3)-1));
const Property& prop = it->second;
double value = this->getValue(prop, X);

if (prop.prescaled)
val = prop.textureData(i+1,j+1,k+1);
else
val = prop.min + (prop.max-prop.min) * prop.textureData(i+1,j+1,k+1);
if (prop.function) {
Vec3 f;
f.x = value;
val = prop.function->getValue(f);
} else
val = value;

return true;
}
Expand All @@ -126,3 +158,21 @@ bool TextureProperties::hasProperty(const std::string& name) const
{
return properties.find(name) != properties.end();
}


double TextureProperties::getValue(const Property& prop, const Vec3& X) const
{
const Vec4* X4 = static_cast<const Vec4*>(&X);
if (!X4)
return false;

int i = std::round(X4->u[0]*(prop.textureData.dim(1)-1));
int j = std::round(X4->u[1]*(prop.textureData.dim(2)-1));
int k = std::round(X4->u[2]*(prop.textureData.dim(3)-1));

if (prop.prescaled)
return prop.textureData(i+1,j+1,k+1);
else
return prop.min + (prop.max-prop.min) * prop.textureData(i+1,j+1,k+1);

}
35 changes: 26 additions & 9 deletions src/Utility/TextureProperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

#include "Function.h"
#include "MatVec.h"

#include <map>
#include <memory>

class TiXmlElement;
class Vec3;
Expand All @@ -38,41 +40,52 @@ class TextureProperties {
//! \param[out] val Property value
bool getProperty(const std::string& name, const Vec3& X, double& val) const;

//! \brief Get value for a vector property
//! \param[in] name Name of property
//! \param[in] X Position (including parameter values) to evaluate property for
//! \param[out] val Property value
bool getProperty(const std::string& name, const Vec3& X, Vec3& val) const;

//! \brief Check if a property is available.
//! \param name Name of property
bool hasProperty(const std::string& name) const;

protected:
//! \brief Struct holding information about a property.
struct Property {
double min; //!< Minimum value
double max; //!< Maximum value
double min = 0.0; //!< Minimum value
double max = 1.0; //!< Maximum value
Matrix3D textureData; //!< Texture data
bool prescaled = false; //!< True if data is already scaled
std::string func_definition; //!< Non-empty if we have a function of the texture value
std::unique_ptr<FunctionBase> function; //!< Function definition for property (if any)
};

//! \brief Obtains texture value for a property.
double getValue(const Property& prop, const Vec3& X) const;

std::map<std::string, Property> properties; //!< Map of available properties
};


//! \brief Class to use a property as a function.
class PropertyFunc : public RealFunc {
template<class Base, class Value>
class PropertyFuncType : public Base {
public:
//! \brief Constructor initializes the members.
//! \param prop Name of property
//! \param props Texture property container
PropertyFunc(const std::string& prop, const TextureProperties& props)
: m_prop(prop), m_props(props)
{}
PropertyFuncType(const std::string& prop, const TextureProperties& props) :
m_prop(prop), m_props(props) {}

//! \brief Empty destructor.
virtual ~PropertyFunc() {}
virtual ~PropertyFuncType() {}

//! \brief Evaluate function in a point.
//! \param X Position to evaluate in
double evaluate(const Vec3& X) const override
Value evaluate(const Vec3& X) const override
{
double val;
Value val;
m_props.getProperty(m_prop, X, val);
return val;
}
Expand All @@ -82,4 +95,8 @@ class PropertyFunc : public RealFunc {
const TextureProperties& m_props; //!< Texture properties container
};


using PropertyFunc = PropertyFuncType<RealFunc,Real>; //!< Convenience type alias for scalars
using PropertyVecFunc = PropertyFuncType<VecFunc,Vec3>; //!< Convenience type alias for vector

#endif

0 comments on commit 107ecfe

Please sign in to comment.