Skip to content

Commit

Permalink
Properties: Support providing TensorXf and Transform3f
Browse files Browse the repository at this point in the history
  • Loading branch information
rtabbara authored and njroussel committed Aug 28, 2023
1 parent 01ea7ba commit d030a3a
Show file tree
Hide file tree
Showing 15 changed files with 505 additions and 186 deletions.
56 changes: 45 additions & 11 deletions include/mitsuba/core/properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,40 @@ class MI_EXPORT_LIB Properties {
public:
/// Supported types of properties
enum class Type {
Bool, /// Boolean value (true/false)
Long, /// 64-bit signed integer
Float, /// Floating point value
Array3f, /// 3D array
Transform, /// 4x4 transform for homogeneous coordinates
AnimatedTransform, /// An animated 4x4 transformation
Color, /// Tristimulus color value
String, /// String
NamedReference, /// Named reference to another named object
Object, /// Arbitrary object
Pointer /// const void* pointer (for internal communication between plugins)
/// Boolean value (true/false)
Bool,
/// 64-bit signed integer
Long,
/// Floating point value
Float,
/// 3D array
Array3f,
/// A tensor of arbitrary shape
Tensor,
/// 3x3 transform for homogeneous coordinates
Transform3f,
/// 4x4 transform for homogeneous coordinates
Transform4f,
/// An animated 4x4 transformation
AnimatedTransform,
/// Tristimulus color value
Color,
/// String
String,
/// Named reference to another named object
NamedReference,
/// Arbitrary object
Object,
/// const void* pointer (for internal communication between plugins)
Pointer
};

// Scene parsing in double precision
using Float = double;
using Array3f = dr::Array<Float, 3>;
// Variant-agnostic handle to TensorXf
using TensorHandle = std::shared_ptr<void>;

MI_IMPORT_CORE_TYPES()

/// Construct an empty property container
Expand Down Expand Up @@ -195,9 +213,15 @@ class MI_EXPORT_LIB Properties {
/// Store a color in the Properties instance
void set_color(const std::string &name, const Color3f &value, bool error_duplicates = true);

/// Store a 3x3 homogeneous coordinate transformation in the Properties instance
void set_transform3f(const std::string &name, const Transform3f &value, bool error_duplicates = true);

/// Store a 4x4 homogeneous coordinate transformation in the Properties instance
void set_transform(const std::string &name, const Transform4f &value, bool error_duplicates = true);

/// Store a tensor handle in the Properties instance
void set_tensor_handle(const std::string &name, const TensorHandle &value, bool error_duplicates = true);

#if 0
/// Store an animated transformation in the Properties instance
void set_animated_transform(const std::string &name, ref<AnimatedTransform> value,
Expand Down Expand Up @@ -361,6 +385,13 @@ class MI_EXPORT_LIB Properties {
return volume<Volume>(name);
}

/// Retrieve a tensor
template <typename Tensor>
Tensor* tensor(const std::string &name) const {
TensorHandle handle = get<Properties::TensorHandle>(name);
return reinterpret_cast<Tensor*>(handle.get());
}

private:
/// Return a reference to an object for a specific name (return null ref if doesn't exist)
ref<Object> find_object(const std::string &name) const;
Expand Down Expand Up @@ -388,8 +419,11 @@ EXTERN_EXPORT_PROPERTY_ACCESSOR(T(Vector<float, 3>))
EXTERN_EXPORT_PROPERTY_ACCESSOR(T(Vector<double, 3>))
EXTERN_EXPORT_PROPERTY_ACCESSOR(T(Color<float, 3>))
EXTERN_EXPORT_PROPERTY_ACCESSOR(T(Color<double, 3>))
EXTERN_EXPORT_PROPERTY_ACCESSOR(T(Transform<Point<float, 3>>))
EXTERN_EXPORT_PROPERTY_ACCESSOR(T(Transform<Point<double, 3>>))
EXTERN_EXPORT_PROPERTY_ACCESSOR(T(Transform<Point<float, 4>>))
EXTERN_EXPORT_PROPERTY_ACCESSOR(T(Transform<Point<double, 4>>))
EXTERN_EXPORT_PROPERTY_ACCESSOR(T(Properties::TensorHandle))
EXTERN_EXPORT_PROPERTY_ACCESSOR(T(std::string))
EXTERN_EXPORT_PROPERTY_ACCESSOR(T(ref<Object>))
#undef T
Expand Down
32 changes: 21 additions & 11 deletions include/mitsuba/python/docstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -5851,27 +5851,31 @@ static const char *__doc_mitsuba_Properties_PropertiesPrivate = R"doc()doc";

static const char *__doc_mitsuba_Properties_Type = R"doc(Supported types of properties)doc";

static const char *__doc_mitsuba_Properties_Type_AnimatedTransform = R"doc(4x4 transform for homogeneous coordinates)doc";
static const char *__doc_mitsuba_Properties_Type_AnimatedTransform = R"doc(An animated 4x4 transformation)doc";

static const char *__doc_mitsuba_Properties_Type_Array3f = R"doc(Floating point value)doc";
static const char *__doc_mitsuba_Properties_Type_Array3f = R"doc(3D array)doc";

static const char *__doc_mitsuba_Properties_Type_Bool = R"doc()doc";
static const char *__doc_mitsuba_Properties_Type_Bool = R"doc(Boolean value (true/false))doc";

static const char *__doc_mitsuba_Properties_Type_Color = R"doc(An animated 4x4 transformation)doc";
static const char *__doc_mitsuba_Properties_Type_Color = R"doc(Tristimulus color value)doc";

static const char *__doc_mitsuba_Properties_Type_Float = R"doc(64-bit signed integer)doc";
static const char *__doc_mitsuba_Properties_Type_Float = R"doc(Floating point value)doc";

static const char *__doc_mitsuba_Properties_Type_Long = R"doc(Boolean value (true/false))doc";
static const char *__doc_mitsuba_Properties_Type_Long = R"doc(64-bit signed integer)doc";

static const char *__doc_mitsuba_Properties_Type_NamedReference = R"doc(String)doc";
static const char *__doc_mitsuba_Properties_Type_NamedReference = R"doc(Named reference to another named object)doc";

static const char *__doc_mitsuba_Properties_Type_Object = R"doc(Named reference to another named object)doc";
static const char *__doc_mitsuba_Properties_Type_Object = R"doc(Arbitrary object)doc";

static const char *__doc_mitsuba_Properties_Type_Pointer = R"doc(Arbitrary object)doc";
static const char *__doc_mitsuba_Properties_Type_Pointer = R"doc(const void* pointer (for internal communication between plugins))doc";

static const char *__doc_mitsuba_Properties_Type_String = R"doc(Tristimulus color value)doc";
static const char *__doc_mitsuba_Properties_Type_String = R"doc(String)doc";

static const char *__doc_mitsuba_Properties_Type_Transform = R"doc(3D array)doc";
static const char *__doc_mitsuba_Properties_Type_Tensor = R"doc(A tensor of arbitrary shape)doc";

static const char *__doc_mitsuba_Properties_Type_Transform3f = R"doc(3x3 transform for homogeneous coordinates)doc";

static const char *__doc_mitsuba_Properties_Type_Transform4f = R"doc(4x4 transform for homogeneous coordinates)doc";

static const char *__doc_mitsuba_Properties_as_string = R"doc(Return one of the parameters (converting it to a string if necessary))doc";

Expand Down Expand Up @@ -5977,10 +5981,16 @@ static const char *__doc_mitsuba_Properties_set_pointer = R"doc(Store an arbitra

static const char *__doc_mitsuba_Properties_set_string = R"doc(Store a string in the Properties instance)doc";

static const char *__doc_mitsuba_Properties_set_tensor_handle = R"doc(Store a tensor handle in the Properties instance)doc";

static const char *__doc_mitsuba_Properties_set_transform =
R"doc(Store a 4x4 homogeneous coordinate transformation in the Properties
instance)doc";

static const char *__doc_mitsuba_Properties_set_transform3f =
R"doc(Store a 3x3 homogeneous coordinate transformation in the Properties
instance)doc";

static const char *__doc_mitsuba_Properties_string = R"doc(Retrieve a string value)doc";

static const char *__doc_mitsuba_Properties_string_2 = R"doc(Retrieve a string value (use default value if no entry exists))doc";
Expand Down
2 changes: 2 additions & 0 deletions include/mitsuba/render/volumegrid.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <drjit/tensor.h>

#include <mitsuba/core/bbox.h>
#include <mitsuba/core/properties.h>
#include <mitsuba/core/spectrum.h>
Expand Down
16 changes: 15 additions & 1 deletion src/core/bitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,13 @@ void Bitmap::read_exr(Stream *stream) {
for (size_t j = 0; j < 4; ++j)
M(i, j) = v->value().x[i][j];
m_metadata.set_transform(name, Transform4f(M));
} else if (type_name == "m33f") {
auto v = static_cast<const Imf::M33fAttribute *>(attr);
Matrix3f M;
for (size_t i = 0; i < 3; ++i)
for (size_t j = 0; j < 3; ++j)
M(i, j) = v->value().x[i][j];
m_metadata.set_transform3f(name, Transform3f(M));
}
}

Expand Down Expand Up @@ -1336,7 +1343,14 @@ void Bitmap::write_exr(Stream *stream, int quality) const {
Imath::V3f((float) val.x(), (float) val.y(), (float) val.z())));
}
break;
case Type::Transform: {
case Type::Transform3f: {
Matrix3f val = metadata.get<ScalarTransform3f>(*it).matrix;
header.insert(it->c_str(), Imf::M33fAttribute(Imath::M33f(
(float) val(0, 0), (float) val(0, 1), (float) val(0, 2),
(float) val(1, 0), (float) val(1, 1), (float) val(1, 2),
(float) val(2, 0), (float) val(2, 1), (float) val(2, 2))));
} break;
case Type::Transform4f: {
Matrix4f val = metadata.get<ScalarTransform4f>(*it).matrix;
header.insert(it->c_str(), Imf::M44fAttribute(Imath::M44f(
(float) val(0, 0), (float) val(0, 1),
Expand Down
49 changes: 44 additions & 5 deletions src/core/properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,31 @@
#include <sstream>
#include <cstring>

#include <drjit/tensor.h>

#include <mitsuba/core/logger.h>
#include <mitsuba/core/properties.h>
#include <mitsuba/core/transform.h>
#include <mitsuba/core/variant.h>

NAMESPACE_BEGIN(mitsuba)

using Float = typename Properties::Float;
using Color3f = typename Properties::Color3f;
using Array3f = typename Properties::Array3f;
using Transform4f = typename Properties::Transform4f;
using Float = typename Properties::Float;
using Color3f = typename Properties::Color3f;
using Array3f = typename Properties::Array3f;
using Transform3f = typename Properties::Transform3f;
using Transform4f = typename Properties::Transform4f;
using TensorHandle = typename Properties::TensorHandle;

using VariantType = variant<
bool,
int64_t,
Float,
Array3f,
std::string,
Transform3f,
Transform4f,
TensorHandle,
Color3f,
NamedReference,
ref<Object>,
Expand Down Expand Up @@ -82,6 +88,23 @@ T get_impl(const Iterator &it) {
return (T const &) it->second.data;
}


/**
* \brief Specialization to gracefully handle if user supplies either a 3x3 or 4x4 transform.
* Historically, we didn't directly support Transform3 properties so want to maintain
* backwards compatibility
*/
template<>
Transform3f get_impl<Transform3f, Transform4f>(const Iterator &it) {
if (!it->second.data.template is<Transform3f>() && !it->second.data.template is<Transform4f>())
Throw("The property \"%s\" has the wrong type (expected <%s> or <%s>, is <%s>)",
it->first, typeid(Transform3f).name(), typeid(Transform4f).name(), it->second.data.type().name());
it->second.queried = true;
if (it->second.data.template is<Transform4f>())
return ((Transform4f const &)it->second.data).extract();
return (Transform3f const &) it->second.data;
}

template <typename T>
T get_routing(const Iterator &it) {
if constexpr (dr::is_static_array_v<T>) {
Expand All @@ -93,6 +116,13 @@ T get_routing(const Iterator &it) {
return (T) get_impl<Array3f>(it);
}

if constexpr (std::is_same_v<T, TensorHandle>)
return get_impl<TensorHandle>(it);

if constexpr (std::is_same_v<T, Transform<Point<float, 3>>> ||
std::is_same_v<T, Transform<Point<double, 3>>>)
return (T) get_impl<Transform3f, Transform4f>(it);

if constexpr (std::is_same_v<T, Transform<Point<float, 4>>> ||
std::is_same_v<T, Transform<Point<double, 4>>>)
return (T) get_impl<Transform4f>(it);
Expand Down Expand Up @@ -171,7 +201,9 @@ T Properties::get(const std::string &name, const T &def_val) const {

DEFINE_PROPERTY_SETTER(bool, set_bool)
DEFINE_PROPERTY_SETTER(int64_t, set_long)
DEFINE_PROPERTY_SETTER(Transform3f, set_transform3f)
DEFINE_PROPERTY_SETTER(Transform4f, set_transform)
DEFINE_PROPERTY_SETTER(TensorHandle, set_tensor_handle)
DEFINE_PROPERTY_SETTER(Color3f, set_color)
DEFINE_PROPERTY_ACCESSOR(std::string, string, set_string, string)
DEFINE_PROPERTY_ACCESSOR(NamedReference, ref, set_named_reference, named_reference)
Expand Down Expand Up @@ -210,7 +242,9 @@ namespace {
Type operator()(const Float &) { return Type::Float; }
Type operator()(const Array3f &) { return Type::Array3f; }
Type operator()(const std::string &) { return Type::String; }
Type operator()(const Transform4f &) { return Type::Transform; }
Type operator()(const Transform3f &) { return Type::Transform3f; }
Type operator()(const Transform4f &) { return Type::Transform4f; }
Type operator()(const TensorHandle &) { return Type::Tensor; }
Type operator()(const Color3f &) { return Type::Color; }
Type operator()(const NamedReference &) { return Type::NamedReference; }
Type operator()(const ref<Object> &) { return Type::Object; }
Expand All @@ -226,7 +260,9 @@ namespace {
void operator()(const Float &f) { os << f; }
void operator()(const Array3f &t) { os << t; }
void operator()(const std::string &s) { os << "\"" << s << "\""; }
void operator()(const Transform3f &t) { os << t; }
void operator()(const Transform4f &t) { os << t; }
void operator()(const TensorHandle &t) { os << t.get(); }
void operator()(const Color3f &t) { os << t; }
void operator()(const NamedReference &nr) { os << "\"" << (const std::string &) nr << "\""; }
void operator()(const ref<Object> &o) { os << o->to_string(); }
Expand Down Expand Up @@ -531,8 +567,11 @@ EXPORT_PROPERTY_ACCESSOR(T(Vector<float, 3>))
EXPORT_PROPERTY_ACCESSOR(T(Vector<double, 3>))
EXPORT_PROPERTY_ACCESSOR(T(Color<float, 3>))
EXPORT_PROPERTY_ACCESSOR(T(Color<double, 3>))
EXPORT_PROPERTY_ACCESSOR(T(Transform<Point<float, 3>>))
EXPORT_PROPERTY_ACCESSOR(T(Transform<Point<double, 3>>))
EXPORT_PROPERTY_ACCESSOR(T(Transform<Point<float, 4>>))
EXPORT_PROPERTY_ACCESSOR(T(Transform<Point<double, 4>>))
EXPORT_PROPERTY_ACCESSOR(T(Properties::TensorHandle))
EXPORT_PROPERTY_ACCESSOR(T(std::string))
EXPORT_PROPERTY_ACCESSOR(T(ref<Object>))
#if defined(__APPLE__)
Expand Down
23 changes: 21 additions & 2 deletions src/core/python/properties_v.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <drjit/tensor.h>

#include <mitsuba/core/properties.h>
#include <mitsuba/core/transform.h>
#include <mitsuba/python/python.h>
Expand Down Expand Up @@ -25,6 +27,10 @@ extern Caster cast_object;

py::object properties_get(const Properties& p, const std::string &key) {
using PFloat = Properties::Float;
using TensorHandle = typename Properties::TensorHandle;
using Float = MI_VARIANT_FLOAT;
using TensorXf = dr::Tensor<mitsuba::DynamicBuffer<Float>>;

// We need to ask for type information to return the right cast
auto type = p.type(key);
if (type == Properties::Type::Bool)
Expand All @@ -41,10 +47,14 @@ py::object properties_get(const Properties& p, const std::string &key) {
return py::cast(p.get<Color<PFloat, 3>>(key));
else if (type == Properties::Type::Array3f)
return py::cast(p.get<dr::Array<PFloat, 3>>(key));
else if (type == Properties::Type::Transform)
else if (type == Properties::Type::Transform3f)
return py::cast(p.get<Transform<Point<PFloat, 3>>>(key));
else if (type == Properties::Type::Transform4f)
return py::cast(p.get<Transform<Point<PFloat, 4>>>(key));
// else if (type == Properties::Type::AnimatedTransform)
// return py::cast(p.animated_transform(key));
else if (type == Properties::Type::Tensor)
return py::cast(*(p.tensor<TensorXf>(key)));
else if (type == Properties::Type::Object)
return cast_object((ref<Object>)p.object(key));
else if (type == Properties::Type::Pointer)
Expand All @@ -58,6 +68,9 @@ MI_PY_EXPORT(Properties) {
MI_PY_CHECK_ALIAS(Properties, "Properties") {
using Color3f = Color<float, 3>;
using Color3d = Color<double, 3>;
using TensorHandle = typename Properties::TensorHandle;
using Float = MI_VARIANT_FLOAT;
using TensorXf = dr::Tensor<mitsuba::DynamicBuffer<Float>>;

auto p = py::class_<Properties>(m, "Properties", D(Properties))
// Constructors
Expand Down Expand Up @@ -92,11 +105,15 @@ MI_PY_EXPORT(Properties) {
.SET_ITEM_BINDING(color, Color3f, py::arg(), py::arg().noconvert())
.SET_ITEM_BINDING(color, Color3d, py::arg(), py::arg().noconvert())
.SET_ITEM_BINDING(array3f, typename Properties::Array3f)
.SET_ITEM_BINDING(transform3f, typename Properties::Transform3f)
.SET_ITEM_BINDING(transform, typename Properties::Transform4f)
// .SET_ITEM_BINDING(animated_transform, ref<AnimatedTransform>)
.SET_ITEM_BINDING(object, ref<Object>)
.GET_ITEM_DEFAULT_BINDING(string, string, std::string)
// .GET_ITEM_DEFAULT_BINDING(animated_transform, animated_transform, ref<AnimatedTransform>)
.def("__setitem__",[](Properties& p, const std::string &key, const TensorXf &value) {
p.set_tensor_handle(key, TensorHandle(std::make_shared<TensorXf>(value)), false);
})
.def("__getitem__", [](const Properties& p, const std::string &key) {
return properties_get(p, key);
}, "key"_a, "Retrieve an existing property given its name")
Expand Down Expand Up @@ -128,8 +145,10 @@ MI_PY_EXPORT(Properties) {
.value("Long", Properties::Type::Long)
.value("Float", Properties::Type::Float)
.value("Array3f", Properties::Type::Array3f)
.value("Transform", Properties::Type::Transform)
.value("Transform3f", Properties::Type::Transform3f)
.value("Transform4f", Properties::Type::Transform4f)
// .value("AnimatedTransform", Properties::Type::AnimatedTransform)
.value("TensorHandle", Properties::Type::Tensor)
.value("Color", Properties::Type::Color)
.value("String", Properties::Type::String)
.value("NamedReference", Properties::Type::NamedReference)
Expand Down
Loading

0 comments on commit d030a3a

Please sign in to comment.