added: allow for defining a function for textureproperties
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'.
This commit is contained in:
parent
d8d4d40d8f
commit
107ecfeb5e
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "TextureProperties.h"
|
#include "TextureProperties.h"
|
||||||
#include "IFEM.h"
|
#include "IFEM.h"
|
||||||
|
#include "Functions.h"
|
||||||
#include "HDF5Reader.h"
|
#include "HDF5Reader.h"
|
||||||
#include "ProcessAdm.h"
|
#include "ProcessAdm.h"
|
||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
@ -33,8 +34,11 @@ void TextureProperties::parse(const TiXmlElement* elem)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string textureFile;
|
std::string textureFile, function;
|
||||||
utl::getAttribute(child, "file", textureFile);
|
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 ||
|
if (textureFile.find(".h5") != std::string::npos ||
|
||||||
textureFile.find(".hdf5") != std::string::npos) {
|
textureFile.find(".hdf5") != std::string::npos) {
|
||||||
@ -73,6 +77,17 @@ void TextureProperties::parse(const TiXmlElement* elem)
|
|||||||
}
|
}
|
||||||
|
|
||||||
properties[prop].textureData.resize(nx,ny,nz);
|
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;
|
const unsigned char* data = image;
|
||||||
for (int i = 1; i <= nx; ++i)
|
for (int i = 1; i <= nx; ++i)
|
||||||
for (int j = 1; j <= ny; ++j)
|
for (int j = 1; j <= ny; ++j)
|
||||||
@ -89,10 +104,13 @@ void TextureProperties::parse(const TiXmlElement* elem)
|
|||||||
|
|
||||||
void TextureProperties::printLog() const
|
void TextureProperties::printLog() const
|
||||||
{
|
{
|
||||||
for (const auto& prop : properties)
|
for (const auto& prop : properties) {
|
||||||
IFEM::cout << "\n\t\tProperty with name " << prop.first
|
IFEM::cout << "\n\t\tProperty with name " << prop.first
|
||||||
<< " (min = " << prop.second.min
|
<< " (min = " << prop.second.min
|
||||||
<< ", max = " << prop.second.max << ")";
|
<< ", max = " << prop.second.max << ")";
|
||||||
|
if (!prop.second.func_definition.empty())
|
||||||
|
IFEM::cout << "\n\t\t\tfunction = " << prop.second.func_definition;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -104,19 +122,33 @@ bool TextureProperties::getProperty(const std::string& name,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
const Property& prop = it->second;
|
const Property& prop = it->second;
|
||||||
|
val = this->getValue(prop, X);
|
||||||
|
|
||||||
const Vec4* X4 = static_cast<const Vec4*>(&X);
|
if (prop.function) {
|
||||||
if (!X4)
|
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;
|
return false;
|
||||||
|
|
||||||
int i = std::round(X4->u[0]*(prop.textureData.dim(1)-1));
|
const Property& prop = it->second;
|
||||||
int j = std::round(X4->u[1]*(prop.textureData.dim(2)-1));
|
double value = this->getValue(prop, X);
|
||||||
int k = std::round(X4->u[2]*(prop.textureData.dim(3)-1));
|
|
||||||
|
|
||||||
if (prop.prescaled)
|
if (prop.function) {
|
||||||
val = prop.textureData(i+1,j+1,k+1);
|
Vec3 f;
|
||||||
else
|
f.x = value;
|
||||||
val = prop.min + (prop.max-prop.min) * prop.textureData(i+1,j+1,k+1);
|
val = prop.function->getValue(f);
|
||||||
|
} else
|
||||||
|
val = value;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -126,3 +158,21 @@ bool TextureProperties::hasProperty(const std::string& name) const
|
|||||||
{
|
{
|
||||||
return properties.find(name) != properties.end();
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
#include "Function.h"
|
#include "Function.h"
|
||||||
#include "MatVec.h"
|
#include "MatVec.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class TiXmlElement;
|
class TiXmlElement;
|
||||||
class Vec3;
|
class Vec3;
|
||||||
@ -38,6 +40,12 @@ public:
|
|||||||
//! \param[out] val Property value
|
//! \param[out] val Property value
|
||||||
bool getProperty(const std::string& name, const Vec3& X, double& val) const;
|
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.
|
//! \brief Check if a property is available.
|
||||||
//! \param name Name of property
|
//! \param name Name of property
|
||||||
bool hasProperty(const std::string& name) const;
|
bool hasProperty(const std::string& name) const;
|
||||||
@ -45,34 +53,39 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
//! \brief Struct holding information about a property.
|
//! \brief Struct holding information about a property.
|
||||||
struct Property {
|
struct Property {
|
||||||
double min; //!< Minimum value
|
double min = 0.0; //!< Minimum value
|
||||||
double max; //!< Maximum value
|
double max = 1.0; //!< Maximum value
|
||||||
Matrix3D textureData; //!< Texture data
|
Matrix3D textureData; //!< Texture data
|
||||||
bool prescaled = false; //!< True if data is already scaled
|
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
|
std::map<std::string, Property> properties; //!< Map of available properties
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! \brief Class to use a property as a function.
|
//! \brief Class to use a property as a function.
|
||||||
class PropertyFunc : public RealFunc {
|
template<class Base, class Value>
|
||||||
|
class PropertyFuncType : public Base {
|
||||||
public:
|
public:
|
||||||
//! \brief Constructor initializes the members.
|
//! \brief Constructor initializes the members.
|
||||||
//! \param prop Name of property
|
//! \param prop Name of property
|
||||||
//! \param props Texture property container
|
//! \param props Texture property container
|
||||||
PropertyFunc(const std::string& prop, const TextureProperties& props)
|
PropertyFuncType(const std::string& prop, const TextureProperties& props) :
|
||||||
: m_prop(prop), m_props(props)
|
m_prop(prop), m_props(props) {}
|
||||||
{}
|
|
||||||
|
|
||||||
//! \brief Empty destructor.
|
//! \brief Empty destructor.
|
||||||
virtual ~PropertyFunc() {}
|
virtual ~PropertyFuncType() {}
|
||||||
|
|
||||||
//! \brief Evaluate function in a point.
|
//! \brief Evaluate function in a point.
|
||||||
//! \param X Position to evaluate in
|
//! \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);
|
m_props.getProperty(m_prop, X, val);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -82,4 +95,8 @@ protected:
|
|||||||
const TextureProperties& m_props; //!< Texture properties container
|
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
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user