Skip to content

Commit a64723a

Browse files
committed
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'.
1 parent d8d4d40 commit a64723a

2 files changed

Lines changed: 80 additions & 17 deletions

File tree

src/Utility/TextureProperties.C

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "TextureProperties.h"
1515
#include "IFEM.h"
16+
#include "Functions.h"
1617
#include "HDF5Reader.h"
1718
#include "ProcessAdm.h"
1819
#include "Utilities.h"
@@ -33,8 +34,11 @@ void TextureProperties::parse(const TiXmlElement* elem)
3334
continue;
3435
}
3536

36-
std::string textureFile;
37+
std::string textureFile, function;
3738
utl::getAttribute(child, "file", textureFile);
39+
utl::getAttribute(child, "function", function);
40+
int comp = 1;
41+
utl::getAttribute(child,"comp",comp);
3842

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

7579
properties[prop].textureData.resize(nx,ny,nz);
80+
if (!function.empty()) {
81+
properties[prop].func_definition = function;
82+
FunctionBase* func;
83+
if (comp == 1)
84+
func = utl::parseRealFunc(function.c_str());
85+
else
86+
func = utl::parseVecFunc(function.c_str());
87+
88+
properties[prop].function.reset(func);
89+
}
90+
7691
const unsigned char* data = image;
7792
for (int i = 1; i <= nx; ++i)
7893
for (int j = 1; j <= ny; ++j)
@@ -89,10 +104,13 @@ void TextureProperties::parse(const TiXmlElement* elem)
89104

90105
void TextureProperties::printLog() const
91106
{
92-
for (const auto& prop : properties)
107+
for (const auto& prop : properties) {
93108
IFEM::cout << "\n\t\tProperty with name " << prop.first
94109
<< " (min = " << prop.second.min
95110
<< ", max = " << prop.second.max << ")";
111+
if (!prop.second.func_definition.empty())
112+
IFEM::cout << "\n\t\t\tfunction = " << prop.second.func_definition;
113+
}
96114
}
97115

98116

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

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

108-
const Vec4* X4 = static_cast<const Vec4*>(&X);
109-
if (!X4)
127+
if (prop.function) {
128+
Vec3 f;
129+
f.x = val;
130+
val = prop.function->getValue(f).front();
131+
}
132+
133+
return true;
134+
}
135+
136+
bool TextureProperties::getProperty(const std::string& name,
137+
const Vec3& X, Vec3& val) const
138+
{
139+
auto it = properties.find(name);
140+
if (it == properties.end())
110141
return false;
111142

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

116-
if (prop.prescaled)
117-
val = prop.textureData(i+1,j+1,k+1);
118-
else
119-
val = prop.min + (prop.max-prop.min) * prop.textureData(i+1,j+1,k+1);
146+
if (prop.function) {
147+
Vec3 f;
148+
f.x = value;
149+
val = prop.function->getValue(f);
150+
} else
151+
val = value;
120152

121153
return true;
122154
}
@@ -126,3 +158,21 @@ bool TextureProperties::hasProperty(const std::string& name) const
126158
{
127159
return properties.find(name) != properties.end();
128160
}
161+
162+
163+
double TextureProperties::getValue(const Property& prop, const Vec3& X) const
164+
{
165+
const Vec4* X4 = static_cast<const Vec4*>(&X);
166+
if (!X4)
167+
return false;
168+
169+
int i = std::round(X4->u[0]*(prop.textureData.dim(1)-1));
170+
int j = std::round(X4->u[1]*(prop.textureData.dim(2)-1));
171+
int k = std::round(X4->u[2]*(prop.textureData.dim(3)-1));
172+
173+
if (prop.prescaled)
174+
return prop.textureData(i+1,j+1,k+1);
175+
else
176+
return prop.min + (prop.max-prop.min) * prop.textureData(i+1,j+1,k+1);
177+
178+
}

src/Utility/TextureProperties.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
#include "Function.h"
1818
#include "MatVec.h"
19+
1920
#include <map>
21+
#include <memory>
2022

2123
class TiXmlElement;
2224
class Vec3;
@@ -38,6 +40,12 @@ class TextureProperties {
3840
//! \param[out] val Property value
3941
bool getProperty(const std::string& name, const Vec3& X, double& val) const;
4042

43+
//! \brief Get value for a vector property
44+
//! \param[in] name Name of property
45+
//! \param[in] X Position (including parameter values) to evaluate property for
46+
//! \param[out] val Property value
47+
bool getProperty(const std::string& name, const Vec3& X, Vec3& val) const;
48+
4149
//! \brief Check if a property is available.
4250
//! \param name Name of property
4351
bool hasProperty(const std::string& name) const;
@@ -49,30 +57,35 @@ class TextureProperties {
4957
double max; //!< Maximum value
5058
Matrix3D textureData; //!< Texture data
5159
bool prescaled = false; //!< True if data is already scaled
60+
std::string func_definition; //!< Non-empty if we have a function of the texture value
61+
std::unique_ptr<FunctionBase> function; //!< Function definition for property (if any)
5262
};
5363

64+
//! \brief Obtains texture value for a property.
65+
double getValue(const Property& prop, const Vec3& X) const;
66+
5467
std::map<std::string, Property> properties; //!< Map of available properties
5568
};
5669

5770

5871
//! \brief Class to use a property as a function.
59-
class PropertyFunc : public RealFunc {
72+
template<class Base=RealFunc, class Value=Real>
73+
class PropertyFunc : public Base {
6074
public:
6175
//! \brief Constructor initializes the members.
6276
//! \param prop Name of property
6377
//! \param props Texture property container
64-
PropertyFunc(const std::string& prop, const TextureProperties& props)
65-
: m_prop(prop), m_props(props)
66-
{}
78+
PropertyFunc(const std::string& prop, const TextureProperties& props) :
79+
m_prop(prop), m_props(props) {}
6780

6881
//! \brief Empty destructor.
6982
virtual ~PropertyFunc() {}
7083

7184
//! \brief Evaluate function in a point.
7285
//! \param X Position to evaluate in
73-
double evaluate(const Vec3& X) const override
86+
Value evaluate(const Vec3& X) const override
7487
{
75-
double val;
88+
Value val;
7689
m_props.getProperty(m_prop, X, val);
7790
return val;
7891
}

0 commit comments

Comments
 (0)