python-related cleanups

metadata
Wenzel Jakob 2011-08-18 19:57:11 -04:00
parent a921c27020
commit faefb39147
10 changed files with 480 additions and 356 deletions

View File

@ -40,10 +40,14 @@ public:
* \param name Title of the progress message * \param name Title of the progress message
* \param formatted Formatted string representation of the message * \param formatted Formatted string representation of the message
* \param eta Estimated time until 100% is reached. * \param eta Estimated time until 100% is reached.
* \param ptr Custom pointer payload * \param ptr Custom pointer payload. This is used to express the
* context of a progress message. When rendering a scene, this
* will usually be the associated \c RenderJob.
* \remark The \c ptr argument is missing in the Python binding
*/ */
virtual void logProgress(Float progress, const std::string &name, virtual void logProgress(Float progress, const std::string &name,
const std::string &formatted, const std::string &eta, const void *ptr) = 0; const std::string &formatted, const std::string &eta,
const void *ptr) = 0;
MTS_DECLARE_CLASS() MTS_DECLARE_CLASS()
protected: protected:

View File

@ -36,6 +36,7 @@ MTS_NAMESPACE_BEGIN
* operating systems). * operating systems).
* *
* \ingroup libcore * \ingroup libcore
* \ingroup libpython
*/ */
class MTS_EXPORT_CORE FileResolver : public Object { class MTS_EXPORT_CORE FileResolver : public Object {
public: public:

View File

@ -686,6 +686,10 @@ template <typename T, int M1, int N1, int M2, int N2> inline Matrix<M1, N2, T>
return result; return result;
} }
template <typename T, int M, int N> inline Matrix<M, N, T> operator*(T f, const Matrix<M, N, T> &m) {
return m*f;
}
/** /**
* \brief Fast 3x3 eigenvalue decomposition * \brief Fast 3x3 eigenvalue decomposition
* *

View File

@ -76,6 +76,9 @@ public:
*/ */
virtual Float average(Float lambdaMin, Float lambdaMax) const; virtual Float average(Float lambdaMin, Float lambdaMax) const;
/// \brief Return a string representation
virtual std::string toString() const = 0;
/// Virtual destructor /// Virtual destructor
virtual ~ContinuousSpectrum() { } virtual ~ContinuousSpectrum() { }
}; };
@ -107,6 +110,9 @@ public:
* per unit wavelength (nm^-1) per steradian (sr^-1) * per unit wavelength (nm^-1) per steradian (sr^-1)
*/ */
virtual Float eval(Float lambda) const; virtual Float eval(Float lambda) const;
/// Return a string representation
std::string toString() const;
private: private:
Float m_temperature; Float m_temperature;
}; };
@ -148,6 +154,9 @@ public:
* The returned value is in units of 1/meter. * The returned value is in units of 1/meter.
*/ */
virtual Float eval(Float lambda) const; virtual Float eval(Float lambda) const;
/// Return a string representation
std::string toString() const;
private: private:
Float m_precomp; Float m_precomp;
}; };
@ -172,6 +181,9 @@ public:
/// Virtual destructor /// Virtual destructor
virtual ~ProductSpectrum() { } virtual ~ProductSpectrum() { }
/// Return a string representation
std::string toString() const;
private: private:
const ContinuousSpectrum &m_spec1; const ContinuousSpectrum &m_spec1;
const ContinuousSpectrum &m_spec2; const ContinuousSpectrum &m_spec2;
@ -196,10 +208,7 @@ public:
* \brief Create a new interpolated spectrum with space * \brief Create a new interpolated spectrum with space
* for the specified number of samples * for the specified number of samples
*/ */
inline InterpolatedSpectrum(size_t size = 0) { InterpolatedSpectrum(size_t size = 0);
m_wavelengths.reserve(size);
m_values.reserve(size);
}
/** /**
* \brief Create a interpolated spectrum instance from * \brief Create a interpolated spectrum instance from
@ -271,7 +280,7 @@ public:
/// Virtual destructor /// Virtual destructor
virtual ~InterpolatedSpectrum() { } virtual ~InterpolatedSpectrum() { }
private: protected:
std::vector<Float> m_wavelengths, m_values; std::vector<Float> m_wavelengths, m_values;
}; };

View File

@ -27,6 +27,7 @@ MTS_NAMESPACE_BEGIN
* \headerfile mitsuba/core/thread.h mitsuba/mitsuba.h * \headerfile mitsuba/core/thread.h mitsuba/mitsuba.h
* \brief Cross-platform thread implementation * \brief Cross-platform thread implementation
* \ingroup libcore * \ingroup libcore
* \ingroup libpython
*/ */
class MTS_EXPORT_CORE Thread : public Object { class MTS_EXPORT_CORE Thread : public Object {
public: public:
@ -47,6 +48,8 @@ public:
* (will be shown in debug messages) * (will be shown in debug messages)
* \param stackSize Initial stack size of the thread * \param stackSize Initial stack size of the thread
* (0 = default) * (0 = default)
* \remark Note that it is currently not possible to
* construct Thread instances from Python
*/ */
Thread(const std::string &name, Thread(const std::string &name,
unsigned int stackSize = 0); unsigned int stackSize = 0);
@ -61,6 +64,9 @@ public:
*/ */
bool setPriority(EThreadPriority priority); bool setPriority(EThreadPriority priority);
/// Return the thread priority
inline EThreadPriority getPriority() const { return m_priority; }
/** /**
* \brief Specify whether or not this thread is critical * \brief Specify whether or not this thread is critical
* *
@ -73,9 +79,6 @@ public:
/// Return the value of the critical flag /// Return the value of the critical flag
inline bool getCritical() const { return m_critical; } inline bool getCritical() const { return m_critical; }
/// Return the thread priority
inline EThreadPriority getPriority() const { return m_priority; }
/// Return the thread's stack size /// Return the thread's stack size
inline int getStackSize() const { return m_stackSize; } inline int getStackSize() const { return m_stackSize; }

View File

@ -18,7 +18,7 @@
#include <mitsuba/mitsuba.h> #include <mitsuba/mitsuba.h>
//#define DEBUG_ALLOCATIONS 1 #define DEBUG_ALLOCATIONS 1
MTS_NAMESPACE_BEGIN MTS_NAMESPACE_BEGIN

View File

@ -440,10 +440,25 @@ Float BlackBodySpectrum::eval(Float l) const {
return (Float) I; return (Float) I;
} }
std::string BlackBodySpectrum::toString() const {
std::ostringstream oss;
oss << "BlackBodySpectrum[temperature=" << m_temperature << "]";
return oss.str();
}
Float ProductSpectrum::eval(Float lambda) const { Float ProductSpectrum::eval(Float lambda) const {
return m_spec1.eval(lambda) * m_spec2.eval(lambda); return m_spec1.eval(lambda) * m_spec2.eval(lambda);
} }
std::string ProductSpectrum::toString() const {
std::ostringstream oss;
oss << "ProductSpectrum["
<< " spec1 = " << indent(m_spec1.toString()) << "," << endl
<< " spec2 = " << indent(m_spec2.toString()) << endl
<< "]";
return oss.str();
}
RayleighSpectrum::RayleighSpectrum(EMode mode, Float eta, Float height) { RayleighSpectrum::RayleighSpectrum(EMode mode, Float eta, Float height) {
/* See ``Display of the Earth Taking into Account Atmospheric Scattering'', /* See ``Display of the Earth Taking into Account Atmospheric Scattering'',
* by Nishita et al., SIGGRAPH 1993 */ * by Nishita et al., SIGGRAPH 1993 */
@ -465,6 +480,10 @@ RayleighSpectrum::RayleighSpectrum(EMode mode, Float eta, Float height) {
} }
} }
std::string RayleighSpectrum::toString() const {
return "RayleighSpectrum[]";
}
Float RayleighSpectrum::eval(Float lambda) const { Float RayleighSpectrum::eval(Float lambda) const {
Float lambdaSqr = lambda*lambda; Float lambdaSqr = lambda*lambda;
return m_precomp / (lambdaSqr*lambdaSqr); return m_precomp / (lambdaSqr*lambdaSqr);
@ -494,6 +513,11 @@ Float ContinuousSpectrum::average(Float lambdaMin, Float lambdaMax) const {
return integral / (lambdaMax - lambdaMin); return integral / (lambdaMax - lambdaMin);
} }
InterpolatedSpectrum::InterpolatedSpectrum(size_t size) {
m_wavelengths.reserve(size);
m_values.reserve(size);
}
InterpolatedSpectrum::InterpolatedSpectrum(const fs::path &path) { InterpolatedSpectrum::InterpolatedSpectrum(const fs::path &path) {
fs::ifstream is(path); fs::ifstream is(path);
if (is.bad() || is.fail()) if (is.bad() || is.fail())
@ -614,7 +638,7 @@ Float InterpolatedSpectrum::eval(Float lambda) const {
if (m_wavelengths.size() < 2 || if (m_wavelengths.size() < 2 ||
lambda < m_wavelengths[0] || lambda < m_wavelengths[0] ||
lambda > m_wavelengths[m_wavelengths.size()-1]) lambda > m_wavelengths[m_wavelengths.size()-1])
return 0; return 0.0f;
/* Find the associated table entries using binary search */ /* Find the associated table entries using binary search */
std::pair<iterator, iterator> result = std::pair<iterator, iterator> result =

View File

@ -2,10 +2,12 @@
#include <mitsuba/core/plugin.h> #include <mitsuba/core/plugin.h>
#include <mitsuba/core/shvector.h> #include <mitsuba/core/shvector.h>
#include <mitsuba/core/fstream.h> #include <mitsuba/core/fstream.h>
#include <mitsuba/core/fresolver.h>
#include <mitsuba/core/statistics.h> #include <mitsuba/core/statistics.h>
#include <mitsuba/core/sched.h> #include <mitsuba/core/sched.h>
#include <mitsuba/core/transform.h> #include <mitsuba/core/transform.h>
#include <mitsuba/core/properties.h> #include <mitsuba/core/properties.h>
#include <mitsuba/core/appender.h>
using namespace mitsuba; using namespace mitsuba;
@ -33,27 +35,25 @@ void shutdownFramework() {
Class::staticShutdown(); Class::staticShutdown();
} }
template <typename T> class fixedsize_wrapper { class spectrum_wrapper {
public: public:
typedef typename T::value_type value_type; static Float get(const Spectrum &spec, int i) {
if (i < 0 || i >= SPECTRUM_SAMPLES) {
static value_type get(const T &vec, int i) {
if (i < 0 || i >= T::dim) {
SLog(EError, "Index %i is out of range!", i); SLog(EError, "Index %i is out of range!", i);
return 0.0f; return 0.0f;
} }
return vec[i]; return spec[i];
} }
static void set(T &vec, int i, value_type value) { static void set(Spectrum &spec, int i, Float value) {
if (i < 0 || i >= T::dim) if (i < 0 || i >= SPECTRUM_SAMPLES)
SLog(EError, "Index %i is out of range!", i); SLog(EError, "Index %i is out of range!", i);
else else
vec[i] = value; spec[i] = value;
} }
static int len(T &) { static int len(Spectrum &) {
return T::dim; return SPECTRUM_SAMPLES;
} }
}; };
@ -116,7 +116,7 @@ struct path_to_python_str {
}; };
void Matrix4x4_setItem(Matrix4x4 *matrix, bp::tuple tuple, Float value) { static void Matrix4x4_setItem(Matrix4x4 *matrix, bp::tuple tuple, Float value) {
if (bp::len(tuple) != 2) if (bp::len(tuple) != 2)
SLog(EError, "Invalid matrix indexing operation, required a tuple of length 2"); SLog(EError, "Invalid matrix indexing operation, required a tuple of length 2");
int i = bp::extract<int>(tuple[0]); int i = bp::extract<int>(tuple[0]);
@ -128,7 +128,7 @@ void Matrix4x4_setItem(Matrix4x4 *matrix, bp::tuple tuple, Float value) {
matrix->operator()(i, j) = value; matrix->operator()(i, j) = value;
} }
Float Matrix4x4_getItem(Matrix4x4 *matrix, bp::tuple tuple) { static Float Matrix4x4_getItem(Matrix4x4 *matrix, bp::tuple tuple) {
if (bp::len(tuple) != 2) if (bp::len(tuple) != 2)
SLog(EError, "Invalid matrix indexing operation, required a tuple of length 2"); SLog(EError, "Invalid matrix indexing operation, required a tuple of length 2");
int i = bp::extract<int>(tuple[0]); int i = bp::extract<int>(tuple[0]);
@ -140,12 +140,55 @@ Float Matrix4x4_getItem(Matrix4x4 *matrix, bp::tuple tuple) {
return matrix->operator()(i, j); return matrix->operator()(i, j);
} }
ref<SerializableObject> instance_manager_getinstance(InstanceManager *manager, Stream *stream) { static ref<SerializableObject> instance_manager_getinstance(InstanceManager *manager, Stream *stream) {
return manager->getInstance(stream); return manager->getInstance(stream);
} }
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(setString_overloads, setString, 2, 3) void appender_logProgress(Appender *appender, Float progress, const std::string &name,
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(getString_overloads, getString, 1, 2) const std::string &formatted, const std::string &eta) {
appender->logProgress(progress, name, formatted, eta, NULL);
}
void mts_log(ELogLevel level, const std::string &msg) {
bp::object traceback(bp::import("traceback"));
bp::object extract_stack(traceback.attr("extract_stack"));
bp::object top(extract_stack()[1]);
Thread::getThread()->getLogger()->log(level,
NULL, bp::extract<const char *>(top[0]),
bp::extract<int>(top[1]),
"%s: %s", (const char *) bp::extract<const char *>(top[2]), msg.c_str());
}
class AppenderWrapper : public Appender, public bp::wrapper<Appender> {
public:
AppenderWrapper(PyObject *self) : m_self(self) { }
void append(ELogLevel level, const std::string &text) {
get_override("append")(level, text);
}
void logProgress(Float progress, const std::string &name,
const std::string &formatted, const std::string &eta,
const void *ptr) {
get_override("logProgress")(progress, name, formatted, eta);
}
private:
PyObject *m_self;
};
static Spectrum *spectrum_array_constructor(bp::list list) {
Float spec[SPECTRUM_SAMPLES];
if (bp::len(list) != SPECTRUM_SAMPLES)
SLog(EError, "Spectrum: expected %i arguments", SPECTRUM_SAMPLES);
for (int i=0; i<bp::len(list); ++i)
spec[i] = bp::extract<Float>(list[i]);
return new Spectrum(spec);
}
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fromLinearRGB_overloads, fromLinearRGB, 3, 4)
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fromXYZ_overloads, fromXYZ, 3, 4)
void export_core() { void export_core() {
boost::python::to_python_converter< boost::python::to_python_converter<
@ -154,22 +197,26 @@ void export_core() {
bp::object coreModule( bp::object coreModule(
bp::handle<>(bp::borrowed(PyImport_AddModule("mitsuba.core")))); bp::handle<>(bp::borrowed(PyImport_AddModule("mitsuba.core"))));
bp::scope().attr("core") = coreModule; bp::scope().attr("core") = coreModule;
bp::scope scope = coreModule; PyObject *oldScope = bp::detail::current_scope;
BP_SETSCOPE(coreModule);
bp::enum_<ELogLevel>("ELogLevel")
.value("ETrace", ETrace)
.value("EDebug", EDebug)
.value("EInfo", EInfo)
.value("EWarn", EWarn)
.value("EError", EError)
.export_values();
bp::def("Log", &mts_log);
bp::class_<Object, ref<Object>, boost::noncopyable>("Object", bp::no_init) bp::class_<Object, ref<Object>, boost::noncopyable>("Object", bp::no_init)
.def("getRefCount", &Object::getRefCount) .def("getRefCount", &Object::getRefCount)
.def("__str__", &Object::toString); .def("__str__", &Object::toString);
BP_DECLARE_CLASS(Stream, Object) stream("Stream", bp::no_init); BP_CLASS(Stream, Object, bp::no_init)
.def("setByteOrder", &Stream::setByteOrder)
bp::scope streamScope = stream;
bp::enum_<Stream::EByteOrder>("EByteOrder")
.value("EBigEndian", Stream::EBigEndian)
.value("ELittleEndian", Stream::ELittleEndian)
.value("ENetworkByteOrder", Stream::ENetworkByteOrder)
.export_values();
stream.def("setByteOrder", &Stream::setByteOrder)
.def("getByteOrder", &Stream::getByteOrder) .def("getByteOrder", &Stream::getByteOrder)
.def("getHostByteOrder", &Stream::getHostByteOrder) .def("getHostByteOrder", &Stream::getHostByteOrder)
.def("truncate", &Stream::truncate) .def("truncate", &Stream::truncate)
@ -208,10 +255,23 @@ void export_core() {
.def("writeDouble", &Stream::writeDouble) .def("writeDouble", &Stream::writeDouble)
.def("readDouble", &Stream::readDouble); .def("readDouble", &Stream::readDouble);
bp::scope scope2 = coreModule; BP_SETSCOPE(Stream_class);
bp::enum_<Stream::EByteOrder>("EByteOrder")
.value("EBigEndian", Stream::EBigEndian)
.value("ELittleEndian", Stream::ELittleEndian)
.value("ENetworkByteOrder", Stream::ENetworkByteOrder)
.export_values();
BP_SETSCOPE(coreModule);
BP_DECLARE_CLASS(FileStream, Stream) fstream("FileStream"); BP_CLASS(FileStream, Stream, bp::init<>())
bp::scope fstreamScope = fstream; .def(bp::init<std::string, FileStream::EFileMode>())
.def("getPath", &FileStream::getPath,
BP_RETURN_CONSTREF)
.def("open", &FileStream::open)
.def("close", &FileStream::close)
.def("remove", &FileStream::remove);
BP_SETSCOPE(FileStream_class);
bp::enum_<FileStream::EFileMode>("EFileMode") bp::enum_<FileStream::EFileMode>("EFileMode")
.value("EReadOnly", FileStream::EReadOnly) .value("EReadOnly", FileStream::EReadOnly)
.value("EReadWrite", FileStream::EReadWrite) .value("EReadWrite", FileStream::EReadWrite)
@ -220,53 +280,126 @@ void export_core() {
.value("EAppendWrite", FileStream::EAppendWrite) .value("EAppendWrite", FileStream::EAppendWrite)
.value("EAppendReadWrite", FileStream::EAppendReadWrite) .value("EAppendReadWrite", FileStream::EAppendReadWrite)
.export_values(); .export_values();
BP_SETSCOPE(coreModule);
fstream BP_CLASS(SerializableObject, Stream, bp::no_init)
.def(bp::init<std::string, FileStream::EFileMode>())
.def("getPath", &FileStream::getPath,
bp::return_value_policy<bp::copy_const_reference>())
.def("open", &FileStream::open)
.def("close", &FileStream::close)
.def("remove", &FileStream::remove);
bp::scope scope3 = coreModule;
BP_DECLARE_CLASS(SerializableObject, Stream)
.def("serialize", &SerializableObject::serialize); .def("serialize", &SerializableObject::serialize);
BP_DECLARE_CLASS(InstanceManager, Object) typedef Object* (Thread::*get_parent_type)();
BP_CLASS(Thread, Object, bp::no_init)
.def("getID", &Thread::getID)
.def("getStackSize", &Thread::getStackSize)
.def("setPriority", &Thread::setPriority)
.def("getPriority", &Thread::getPriority)
.def("setCritical", &Thread::setCritical)
.def("getCritical", &Thread::getCritical)
.def("setName", &Thread::setName)
.def("getName", &Thread::getName, BP_RETURN_CONSTREF)
// .def("getParent", (get_parent_type) &Thread::getParent)
// .def("setLogger", &Thread::setLogger)
// .def("getLogger", &Thread::getLogger)
// .def("setFileResolver", &Thread::setFileResolver)
// .def("getFileResolver", &Thread::getFileResolver)
.def("getThread", &Thread::getThread, bp::return_internal_reference<>())
.def("isRunning", &Thread::isRunning)
.def("sleep", &Thread::sleep)
.def("detach", &Thread::detach)
.def("join", &Thread::join)
.def("start", &Thread::start)
.staticmethod("sleep")
.staticmethod("getThread");
BP_SETSCOPE(Thread_class);
bp::enum_<Thread::EThreadPriority>("EThreadPriority")
.value("EIdlePriority", Thread::EIdlePriority)
.value("ELowestPriority", Thread::ELowestPriority)
.value("ELowPriority", Thread::ELowPriority)
.value("ENormalPriority", Thread::ENormalPriority)
.value("EHighPriority", Thread::EHighPriority)
.value("EHighestPriority", Thread::EHighestPriority)
.value("ERealtimePriority", Thread::ERealtimePriority)
.export_values();
BP_SETSCOPE(coreModule);
BP_WRAPPED_CLASS(Appender, AppenderWrapper, Object, bp::init<>())
.def("append", &Appender::append)
.def("logProgress", &appender_logProgress);
BP_CLASS(InstanceManager, Object, bp::init<>())
.def("serialize", &InstanceManager::serialize) .def("serialize", &InstanceManager::serialize)
.def("getInstance", &instance_manager_getinstance); .def("getInstance", &instance_manager_getinstance);
BP_DECLARE_CLASS(ContinuousSpectrum, SerializableObject) bp::class_<ContinuousSpectrum, boost::noncopyable>("ContinuousSpectrum", bp::no_init)
.def("eval", &ContinuousSpectrum::eval) .def("eval", &ContinuousSpectrum::eval)
.def("average", &ContinuousSpectrum::average); .def("average", &ContinuousSpectrum::average)
.def("__str__", &ContinuousSpectrum::toString);
BP_DECLARE_CLASS(InterpolatedSpectrum, ContinuousSpectrum) bp::class_<InterpolatedSpectrum, bp::bases<ContinuousSpectrum>, boost::noncopyable>
("InterpolatedSpectrum", bp::init<>())
.def(bp::init<size_t>())
.def(bp::init<fs::path>())
.def("append", &InterpolatedSpectrum::append) .def("append", &InterpolatedSpectrum::append)
.def("clear", &InterpolatedSpectrum::clear) .def("clear", &InterpolatedSpectrum::clear)
.def("zeroExtend", &ContinuousSpectrum::zeroExtend); .def("zeroExtend", &InterpolatedSpectrum::zeroExtend);
BP_STRUCT(Spectrum, bp::init<>())
.def("__init__", bp::make_constructor(spectrum_array_constructor))
.def(bp::init<Float>())
.def(bp::init<Stream *>())
.def(bp::self != bp::self)
.def(bp::self == bp::self)
.def(-bp::self)
.def(bp::self + bp::self)
.def(bp::self += bp::self)
.def(bp::self - bp::self)
.def(bp::self -= bp::self)
.def(bp::self *= Float())
.def(bp::self * Float())
.def(bp::self *= bp::self)
.def(bp::self * bp::self)
.def(bp::self / Float())
.def(bp::self /= Float())
.def(bp::self /= bp::self)
.def(bp::self / bp::self)
.def("isValid", &Spectrum::isValid)
.def("isNaN", &Spectrum::isNaN)
.def("average", &Spectrum::average)
.def("sqrt", &Spectrum::sqrt)
.def("exp", &Spectrum::exp)
.def("pow", &Spectrum::pow)
.def("clampNegative", &Spectrum::clampNegative)
.def("min", &Spectrum::min)
.def("max", &Spectrum::max)
.def("isZero", &Spectrum::isZero)
.def("eval", &Spectrum::eval)
.def("getLuminance", &Spectrum::getLuminance)
.def("fromXYZ", &Spectrum::fromXYZ, fromXYZ_overloads())
.def("toXYZ", &Spectrum::toXYZ)
.def("fromLinearRGB", &Spectrum::fromLinearRGB, fromLinearRGB_overloads())
.def("toLinearRGB", &Spectrum::toLinearRGB)
.def("fromSRGB", &Spectrum::fromSRGB)
.def("toSRGB", &Spectrum::toSRGB)
.def("fromContinuousSpectrum", &Spectrum::fromContinuousSpectrum)
.def("serialize", &Spectrum::serialize)
.def("__str__", &Spectrum::toString)
.def("__len__", &spectrum_wrapper::len)
.def("__getitem__", &spectrum_wrapper::get)
.def("__setitem__", &spectrum_wrapper::set);
BP_SETSCOPE(Spectrum_struct);
bp::enum_<Spectrum::EConversionIntent>("EConversionIntent")
.value("EReflectance", Spectrum::EReflectance)
.value("EIlluminant", Spectrum::EIlluminant)
.export_values();
BP_SETSCOPE(coreModule);
bp::class_<Properties> properties("Properties"); bp::class_<Properties> properties("Properties");
bp::scope propertiesScope = properties;
bp::enum_<Properties::EPropertyType>("EPropertyType")
.value("EBoolean", Properties::EBoolean)
.value("EInteger", Properties::EInteger)
.value("EFloat", Properties::EFloat)
.value("EPoint", Properties::EPoint)
.value("ETransform", Properties::ETransform)
.value("ESpectrum", Properties::ESpectrum)
.value("EString", Properties::EString)
.value("EData", Properties::EData)
.export_values();
properties properties
.def(bp::init<std::string>()) .def(bp::init<std::string>())
.def("getPluginName", &Properties::getPluginName, .def("getPluginName", &Properties::getPluginName, BP_RETURN_CONSTREF)
bp::return_value_policy<bp::copy_const_reference>())
.def("setPluginName", &Properties::setPluginName) .def("setPluginName", &Properties::setPluginName)
.def("getID", &Properties::getPluginName, .def("getID", &Properties::getPluginName, BP_RETURN_CONSTREF)
bp::return_value_policy<bp::copy_const_reference>())
.def("setID", &Properties::setPluginName) .def("setID", &Properties::setPluginName)
.def("getType", &Properties::getType) .def("getType", &Properties::getType)
.def("getNames", &Properties::getNames) .def("getNames", &Properties::getNames)
@ -278,268 +411,130 @@ void export_core() {
.def("__contains__", &Properties::hasProperty) .def("__contains__", &Properties::hasProperty)
.def("__str__", &Properties::toString); .def("__str__", &Properties::toString);
bp::scope scope4 = coreModule; BP_SETSCOPE(properties);
bp::class_<Vector2>("Vector2", bp::init<Float, Float>()) bp::enum_<Properties::EPropertyType>("EPropertyType")
.def(bp::init<Float>()) .value("EBoolean", Properties::EBoolean)
.value("EInteger", Properties::EInteger)
.value("EFloat", Properties::EFloat)
.value("EPoint", Properties::EPoint)
.value("ETransform", Properties::ETransform)
.value("ESpectrum", Properties::ESpectrum)
.value("EString", Properties::EString)
.value("EData", Properties::EData)
.export_values();
BP_SETSCOPE(coreModule);
BP_STRUCT(Vector2, bp::init<>())
.def(bp::init<Float, Float>())
.def(bp::init<Point2>()) .def(bp::init<Point2>())
.def(bp::init<Stream *>())
.def_readwrite("x", &Vector2::x) .def_readwrite("x", &Vector2::x)
.def_readwrite("y", &Vector2::y) .def_readwrite("y", &Vector2::y);
.def("length", &Vector2::length)
.def(bp::self != bp::self)
.def(bp::self == bp::self)
.def(-bp::self)
.def(bp::self + bp::self)
.def(bp::self += bp::self)
.def(bp::self - bp::self)
.def(bp::self -= bp::self)
.def(bp::self *= Float())
.def(bp::self * Float())
.def(bp::self / Float())
.def(bp::self /= Float())
.def("serialize", &Vector2::serialize)
.def("__str__", &Vector2::toString)
.def("__len__", &fixedsize_wrapper<Vector2>::len)
.def("__getitem__", &fixedsize_wrapper<Vector2>::get)
.def("__setitem__", &fixedsize_wrapper<Vector2>::set);
bp::class_<Point2>("Point2", bp::init<Float, Float>()) BP_STRUCT(Vector2i, bp::init<>())
.def(bp::init<Float>()) .def(bp::init<int, int>())
.def(bp::init<Vector2>()) .def(bp::init<Point2i>())
.def(bp::init<Stream *>()) .def_readwrite("x", &Vector2i::x)
.def_readwrite("x", &Point2::x) .def_readwrite("y", &Vector2i::y);
.def_readwrite("y", &Point2::y)
.def(bp::self != bp::self)
.def(bp::self == bp::self)
.def(-bp::self)
.def(bp::self + bp::self)
.def(bp::self += bp::self)
.def(bp::self - bp::self)
.def(bp::self *= Float())
.def(bp::self * Float())
.def(bp::self / Float())
.def(bp::self /= Float())
.def("serialize", &Point2::serialize)
.def("__str__", &Point2::toString)
.def("__len__", &fixedsize_wrapper<Point2>::len)
.def("__getitem__", &fixedsize_wrapper<Point2>::get)
.def("__setitem__", &fixedsize_wrapper<Point2>::set);
bp::class_<Vector>("Vector", bp::init<Float, Float, Float>()) BP_STRUCT(Vector3, bp::init<>())
.def(bp::init<Float>()) .def(bp::init<Float, Float, Float>())
.def(bp::init<Point>()) .def(bp::init<Point3>())
.def(bp::init<Normal>()) .def(bp::init<Normal>())
.def(bp::init<Stream *>()) .def_readwrite("x", &Vector3::x)
.def_readwrite("x", &Vector::x) .def_readwrite("y", &Vector3::y)
.def_readwrite("y", &Vector::y) .def_readwrite("z", &Vector3::z);
.def_readwrite("z", &Vector::z)
.def("length", &Vector::length)
.def(bp::self != bp::self)
.def(bp::self == bp::self)
.def(-bp::self)
.def(bp::self + bp::self)
.def(bp::self += bp::self)
.def(bp::self - bp::self)
.def(bp::self -= bp::self)
.def(bp::self *= Float())
.def(bp::self * Float())
.def(bp::self / Float())
.def(bp::self /= Float())
.def("serialize", &Vector::serialize)
.def("__str__", &Vector::toString)
.def("__len__", &fixedsize_wrapper<Vector>::len)
.def("__getitem__", &fixedsize_wrapper<Vector>::get)
.def("__setitem__", &fixedsize_wrapper<Vector>::set);
bp::class_<Normal>("Normal", bp::init<Float, Float, Float>()) BP_STRUCT(Normal, bp::init<>())
.def(bp::init<Float>()) .def(bp::init<Float, Float, Float>())
.def(bp::init<Vector>()) .def(bp::init<Vector>())
.def(bp::init<Stream *>())
.def_readwrite("x", &Normal::x) .def_readwrite("x", &Normal::x)
.def_readwrite("y", &Normal::y) .def_readwrite("y", &Normal::y)
.def_readwrite("z", &Normal::z) .def_readwrite("z", &Normal::z);
.def("length", &Normal::length)
.def(bp::self != bp::self)
.def(bp::self == bp::self)
.def(-bp::self)
.def(bp::self + bp::self)
.def(bp::self += bp::self)
.def(bp::self - bp::self)
.def(bp::self -= bp::self)
.def(bp::self *= Float())
.def(bp::self * Float())
.def(bp::self / Float())
.def(bp::self /= Float())
.def("serialize", &Normal::serialize)
.def("__str__", &Normal::toString)
.def("__len__", &fixedsize_wrapper<Normal>::len)
.def("__getitem__", &fixedsize_wrapper<Normal>::get)
.def("__setitem__", &fixedsize_wrapper<Normal>::set);
bp::class_<Point>("Point", bp::init<Float, Float, Float>()) BP_STRUCT(Vector3i, bp::init<>())
.def(bp::init<Float>()) .def(bp::init<int, int, int>())
.def(bp::init<Vector>()) .def(bp::init<Point3i>())
.def(bp::init<Stream *>()) .def_readwrite("x", &Vector3i::x)
.def_readwrite("x", &Point::x) .def_readwrite("y", &Vector3i::y)
.def_readwrite("y", &Point::y) .def_readwrite("z", &Vector3i::z);
.def_readwrite("z", &Point::z)
.def(bp::self != bp::self)
.def(bp::self == bp::self)
.def(-bp::self)
.def(bp::self + bp::self)
.def(bp::self += bp::self)
.def(bp::self - bp::self)
.def(bp::self *= Float())
.def(bp::self * Float())
.def(bp::self / Float())
.def(bp::self /= Float())
.def("serialize", &Point::serialize)
.def("__str__", &Point::toString)
.def("__len__", &fixedsize_wrapper<Point>::len)
.def("__getitem__", &fixedsize_wrapper<Point>::get)
.def("__setitem__", &fixedsize_wrapper<Point>::set);
bp::class_<Vector4>("Vector4", bp::init<Float, Float, Float, Float>()) BP_STRUCT(Vector4, bp::init<>())
.def(bp::init<Float>()) .def(bp::init<Float, Float, Float, Float>())
.def(bp::init<Point4>()) .def(bp::init<Point4>())
.def(bp::init<Stream *>())
.def_readwrite("x", &Vector4::x) .def_readwrite("x", &Vector4::x)
.def_readwrite("y", &Vector4::y) .def_readwrite("y", &Vector4::y)
.def_readwrite("z", &Vector4::z) .def_readwrite("z", &Vector4::z)
.def_readwrite("w", &Vector4::w) .def_readwrite("w", &Vector4::w);
.def("length", &Vector4::length)
.def(bp::self != bp::self)
.def(bp::self == bp::self)
.def(-bp::self)
.def(bp::self + bp::self)
.def(bp::self += bp::self)
.def(bp::self - bp::self)
.def(bp::self -= bp::self)
.def(bp::self *= Float())
.def(bp::self * Float())
.def(bp::self / Float())
.def(bp::self /= Float())
.def("serialize", &Vector4::serialize)
.def("__str__", &Vector4::toString)
.def("__len__", &fixedsize_wrapper<Vector4>::len)
.def("__getitem__", &fixedsize_wrapper<Vector4>::get)
.def("__setitem__", &fixedsize_wrapper<Vector4>::set);
bp::class_<Point4>("Point4", bp::init<Float, Float, Float, Float>()) BP_STRUCT(Vector4i, bp::init<>())
.def(bp::init<Float>()) .def(bp::init<int, int, int, int>())
.def(bp::init<Point4i>())
.def_readwrite("x", &Vector4i::x)
.def_readwrite("y", &Vector4i::y)
.def_readwrite("z", &Vector4i::z)
.def_readwrite("w", &Vector4i::w);
BP_STRUCT(Point2, bp::init<>())
.def(bp::init<Float, Float>())
.def(bp::init<Vector2>())
.def_readwrite("x", &Point2::x)
.def_readwrite("y", &Point2::y);
BP_STRUCT(Point2i, bp::init<>())
.def(bp::init<int, int>())
.def(bp::init<Vector2i>())
.def_readwrite("x", &Point2i::x)
.def_readwrite("y", &Point2i::y);
BP_STRUCT(Point3, bp::init<>())
.def(bp::init<Float, Float, Float>())
.def(bp::init<Vector3>())
.def(bp::init<Normal>())
.def_readwrite("x", &Point3::x)
.def_readwrite("y", &Point3::y)
.def_readwrite("z", &Point3::z);
BP_STRUCT(Point3i, bp::init<>())
.def(bp::init<int, int, int>())
.def(bp::init<Vector3i>())
.def_readwrite("x", &Point3i::x)
.def_readwrite("y", &Point3i::y)
.def_readwrite("z", &Point3i::z);
BP_STRUCT(Point4, bp::init<>())
.def(bp::init<Float, Float, Float, Float>())
.def(bp::init<Vector4>()) .def(bp::init<Vector4>())
.def(bp::init<Stream *>())
.def_readwrite("x", &Point4::x) .def_readwrite("x", &Point4::x)
.def_readwrite("y", &Point4::y) .def_readwrite("y", &Point4::y)
.def_readwrite("z", &Point4::z) .def_readwrite("z", &Point4::z)
.def_readwrite("w", &Point4::w) .def_readwrite("w", &Point4::w);
.def(bp::self != bp::self)
.def(bp::self == bp::self)
.def(-bp::self)
.def(bp::self + bp::self)
.def(bp::self += bp::self)
.def(bp::self - bp::self)
.def(bp::self *= Float())
.def(bp::self * Float())
.def(bp::self / Float())
.def(bp::self /= Float())
.def("serialize", &Point4::serialize)
.def("__str__", &Point4::toString)
.def("__len__", &fixedsize_wrapper<Point4>::len)
.def("__getitem__", &fixedsize_wrapper<Point4>::get)
.def("__setitem__", &fixedsize_wrapper<Point4>::set);
bp::class_<Vector2i>("Vector2i", bp::init<int, int>()) BP_STRUCT(Point4i, bp::init<>())
.def(bp::init<int>()) .def(bp::init<int, int, int, int>())
.def(bp::init<Point2i>()) .def(bp::init<Vector4i>())
.def(bp::init<Stream *>()) .def_readwrite("x", &Point4i::x)
.def_readwrite("x", &Vector2i::x) .def_readwrite("y", &Point4i::y)
.def_readwrite("y", &Vector2i::y) .def_readwrite("z", &Point4i::z)
.def(bp::self != bp::self) .def_readwrite("w", &Point4i::w);
.def(bp::self == bp::self)
.def(-bp::self)
.def(bp::self + bp::self)
.def(bp::self += bp::self)
.def(bp::self - bp::self)
.def(bp::self -= bp::self)
.def(bp::self *= int())
.def(bp::self * int())
.def(bp::self / int())
.def(bp::self /= int())
.def("serialize", &Vector2i::serialize)
.def("__str__", &Vector2i::toString)
.def("__len__", &fixedsize_wrapper<Vector2i>::len)
.def("__getitem__", &fixedsize_wrapper<Vector2i>::get)
.def("__setitem__", &fixedsize_wrapper<Vector2i>::set);
bp::class_<Point2i>("Point2i", bp::init<int, int>()) BP_IMPLEMENT_VECTOR_OPS(Normal, Float, 3);
.def(bp::init<int>()) BP_IMPLEMENT_VECTOR_OPS(Vector2i, int, 2);
.def(bp::init<Vector2i>()) BP_IMPLEMENT_VECTOR_OPS(Vector3i, int, 3);
.def(bp::init<Stream *>()) BP_IMPLEMENT_VECTOR_OPS(Vector4i, int, 3);
.def_readwrite("x", &Point2i::x) BP_IMPLEMENT_VECTOR_OPS(Vector2, Float, 2);
.def_readwrite("y", &Point2i::y) BP_IMPLEMENT_VECTOR_OPS(Vector3, Float, 3);
.def(bp::self != bp::self) BP_IMPLEMENT_VECTOR_OPS(Vector4, Float, 3);
.def(bp::self == bp::self) BP_IMPLEMENT_POINT_OPS(Point2i, int, 2);
.def(-bp::self) BP_IMPLEMENT_POINT_OPS(Point3i, int, 3);
.def(bp::self + bp::self) BP_IMPLEMENT_POINT_OPS(Point4i, int, 3);
.def(bp::self += bp::self) BP_IMPLEMENT_POINT_OPS(Point2, Float, 2);
.def(bp::self - bp::self) BP_IMPLEMENT_POINT_OPS(Point3, Float, 3);
.def(bp::self *= int()) BP_IMPLEMENT_POINT_OPS(Point4, Float, 3);
.def(bp::self * int())
.def(bp::self / int())
.def(bp::self /= int())
.def("serialize", &Point2i::serialize)
.def("__str__", &Point2i::toString)
.def("__len__", &fixedsize_wrapper<Point2i>::len)
.def("__getitem__", &fixedsize_wrapper<Point2i>::get)
.def("__setitem__", &fixedsize_wrapper<Point2i>::set);
bp::class_<Vector3i>("Vector3i", bp::init<int, int, int>()) bp::scope().attr("Vector") = bp::scope().attr("Vector3");
.def(bp::init<int>()) bp::scope().attr("Point") = bp::scope().attr("Point3");
.def(bp::init<Point3i>())
.def(bp::init<Stream *>())
.def_readwrite("x", &Vector3i::x)
.def_readwrite("y", &Vector3i::y)
.def_readwrite("z", &Vector3i::z)
.def(bp::self != bp::self)
.def(bp::self == bp::self)
.def(-bp::self)
.def(bp::self + bp::self)
.def(bp::self += bp::self)
.def(bp::self - bp::self)
.def(bp::self -= bp::self)
.def(bp::self *= int())
.def(bp::self * int())
.def(bp::self / int())
.def(bp::self /= int())
.def("serialize", &Vector3i::serialize)
.def("__str__", &Vector3i::toString)
.def("__len__", &fixedsize_wrapper<Vector3i>::len)
.def("__getitem__", &fixedsize_wrapper<Vector3i>::get)
.def("__setitem__", &fixedsize_wrapper<Vector3i>::set);
bp::class_<Point3i>("Point3i", bp::init<int, int, int>())
.def(bp::init<int>())
.def(bp::init<Vector3i>())
.def(bp::init<Stream *>())
.def_readwrite("x", &Point3i::x)
.def_readwrite("y", &Point3i::y)
.def_readwrite("z", &Point3i::z)
.def(bp::self != bp::self)
.def(bp::self == bp::self)
.def(-bp::self)
.def(bp::self + bp::self)
.def(bp::self += bp::self)
.def(bp::self - bp::self)
.def(bp::self *= int())
.def(bp::self * int())
.def(bp::self / int())
.def(bp::self /= int())
.def("serialize", &Point3i::serialize)
.def("__str__", &Point3i::toString)
.def("__len__", &fixedsize_wrapper<Point3i>::len)
.def("__getitem__", &fixedsize_wrapper<Point3i>::get)
.def("__setitem__", &fixedsize_wrapper<Point3i>::set);
bp::class_<Matrix4x4>("Matrix4x4", bp::init<Float>()) bp::class_<Matrix4x4>("Matrix4x4", bp::init<Float>())
.def(bp::init<Stream *>()) .def(bp::init<Stream *>())
@ -562,12 +557,15 @@ void export_core() {
.def(bp::self - Float()) .def(bp::self - Float())
.def(bp::self -= Float()) .def(bp::self -= Float())
.def(bp::self * Float()) .def(bp::self * Float())
.def(Float() * bp::self)
.def(bp::self *= Float()) .def(bp::self *= Float())
.def(bp::self * bp::self) .def(bp::self * bp::self)
.def(bp::self *= bp::self) .def(bp::self *= bp::self)
.def(bp::self / Float()) .def(bp::self / Float())
.def(bp::self /= Float()) .def(bp::self /= Float())
.def("__str__", &Matrix4x4::toString); .def("__str__", &Matrix4x4::toString);
bp::detail::current_scope = oldScope;
} }
BOOST_PYTHON_MODULE(mitsuba) { BOOST_PYTHON_MODULE(mitsuba) {

View File

@ -21,8 +21,67 @@
#include <mitsuba/mitsuba.h> #include <mitsuba/mitsuba.h>
#define BP_DECLARE_CLASS(Name, Base) \ #define BP_STRUCT(Name, Init) \
bp::class_<Name, ref<Name>, bp::bases<Base>, boost::noncopyable> bp::class_<Name> Name ##_struct(#Name, Init); \
Name ##_struct
#define BP_CLASS(Name, Base, Init) \
bp::class_<Name, ref<Name>, bp::bases<Base>, boost::noncopyable> Name ##_class(#Name, Init); \
Name ##_class
#define BP_WRAPPED_CLASS(Name, Wrapper, Base, Init) \
bp::class_<Name, ref<Wrapper>, bp::bases<Base>, boost::noncopyable> Name ##_class(#Name, Init); \
Name ##_class
#define BP_IMPLEMENT_VECTOR_OPS(Name, Scalar, Size) \
Name ##_struct \
.def(bp::init<Stream *>()) \
.def(bp::self != bp::self) \
.def(bp::self == bp::self) \
.def(-bp::self) \
.def(bp::self + bp::self) \
.def(bp::self += bp::self) \
.def(bp::self - bp::self) \
.def(bp::self -= bp::self) \
.def(bp::self *= Scalar()) \
.def(bp::self * Scalar()) \
.def(Scalar() * bp::self) \
.def(bp::self / Scalar()) \
.def(bp::self /= Scalar()) \
.def("serialize", &Name::serialize) \
.def("__str__", &Name::toString) \
.def("__len__", &FixedSizeSupport<Name, Scalar, Size>::len) \
.def("__getitem__", &FixedSizeSupport<Name, Scalar, Size>::get) \
.def("__setitem__", &FixedSizeSupport<Name, Scalar, Size>::set)
#define BP_IMPLEMENT_POINT_OPS(Name, Scalar, Size) \
Name ##_struct \
.def(bp::init<Stream *>()) \
.def(bp::self != bp::self) \
.def(bp::self == bp::self) \
.def(Scalar() * bp::self) \
.def(-bp::self) \
.def(bp::self + Name::vector_type()) \
.def(bp::self += Name::vector_type()) \
.def(bp::self - Name::vector_type()) \
.def(bp::self -= Name::vector_type()) \
.def(bp::self - bp::self) \
.def(bp::self *= Scalar()) \
.def(bp::self * Scalar()) \
.def(bp::self / Scalar()) \
.def(bp::self /= Scalar()) \
.def("serialize", &Name::serialize) \
.def("__str__", &Name::toString) \
.def("__len__", &FixedSizeSupport<Name, Scalar, Size>::len) \
.def("__getitem__", &FixedSizeSupport<Name, Scalar, Size>::get) \
.def("__setitem__", &FixedSizeSupport<Name, Scalar, Size>::set)
#define BP_SETSCOPE(value) do { \
bp::detail::current_scope = value.ptr(); \
} while (0);
#define BP_RETURN_CONSTREF bp::return_value_policy<bp::copy_const_reference>()
#define BP_RETURN_INTREF bp::return_internal_reference<>
namespace boost { namespace boost {
namespace python { namespace python {
@ -50,9 +109,31 @@ namespace boost {
} }
} }
template <typename T> void registerClass() { template <typename T, typename Scalar, int Size> class FixedSizeSupport {
boost::python::register_ptr_to_python< mitsuba::ref<T> >(); public:
static Scalar get(const T &value, int i) {
using namespace mitsuba;
if (i < 0 || i >= Size) {
SLog(EError, "Index %i is out of range!", i);
return 0.0f;
} }
return value[i];
}
static void set(T &value, int i, Scalar arg) {
using namespace mitsuba;
if (i < 0 || i >= Size)
SLog(EError, "Index %i is out of range!", i);
else
value[i] = arg;
}
static int len(const T &) {
return Size;
}
};
typedef std::vector<std::string> StringVector; typedef std::vector<std::string> StringVector;
typedef std::map<std::string, std::string> StringMap; typedef std::map<std::string, std::string> StringMap;

View File

@ -2,7 +2,7 @@ Import('env', 'plugins')
plugins += env.SharedLibrary('obj', ['obj.cpp']) plugins += env.SharedLibrary('obj', ['obj.cpp'])
plugins += env.SharedLibrary('ply', ['ply/ply.cpp', 'ply/ply_parser.cpp'], plugins += env.SharedLibrary('ply', ['ply/ply.cpp', 'ply/ply_parser.cpp'],
CPPPATH = env['CPPPATH'] + ['ply', '#dependencies']) CPPPATH = env['CPPPATH'] + ['ply'])
plugins += env.SharedLibrary('serialized', ['serialized.cpp']) plugins += env.SharedLibrary('serialized', ['serialized.cpp'])
plugins += env.SharedLibrary('sphere', ['sphere.cpp']) plugins += env.SharedLibrary('sphere', ['sphere.cpp'])
plugins += env.SharedLibrary('cylinder', ['cylinder.cpp']) plugins += env.SharedLibrary('cylinder', ['cylinder.cpp'])