python binding improvements
parent
0a766c8c22
commit
e58a0fa338
|
@ -95,7 +95,7 @@ If all goes well, SCons should finish successfully within a few minutes:
|
|||
\begin{shell}
|
||||
scons: $\texttt{done}$ building targets.
|
||||
\end{shell}
|
||||
To be able to run the renderer from the command line, you will also have to import it into your path:
|
||||
To be able to run the renderer from the command line, you will first have to import it into your path:
|
||||
\begin{shell}
|
||||
$\text{\$}$ . setpath.sh
|
||||
\end{shell}
|
||||
|
@ -173,7 +173,7 @@ If all goes well, SCons should finish successfully within a few minutes:
|
|||
\begin{shell}
|
||||
scons: $\texttt{done}$ building targets.
|
||||
\end{shell}
|
||||
To be able to run the renderer from the command line, you will also have to import it into your path:
|
||||
To be able to run the renderer from the command line, you will first have to import it into your path:
|
||||
\begin{shell}
|
||||
$\text{\$}$ . setpath.sh
|
||||
\end{shell}
|
||||
|
@ -199,71 +199,42 @@ $\text{\$}$ rpmbuild -bb mitsuba-$\code{\MitsubaVersion}$/data/linux/fedora/mits
|
|||
\end{shell}
|
||||
After this command finishes, its output can be found in the directory \code{rpmbuild/RPMS}.
|
||||
\subsection{Building on Arch Linux}
|
||||
You'll first need to install a number of dependencies.
|
||||
|
||||
First, run
|
||||
You'll first need to install a number of dependencies: run
|
||||
\begin{shell}
|
||||
$\text{\$}$ sudo pacman -S gcc xerces-c glew openexr boost libpng libjpeg qt scons mercurial python
|
||||
\end{shell}
|
||||
|
||||
|
||||
There are two ways to install Mitsuba on Archlinux, the Arch way, and the other way.
|
||||
|
||||
The Arch Way is to use the Aur software repository.
|
||||
Accessing software in the Aur repository is easiest when using a script called \texttt{packer}.
|
||||
|
||||
First download packer then use \texttt{makepkg} to build and install it.
|
||||
The \texttt{-is} flags will prompt you for your sudo password and then install the package after it has finished building as well as install any needed dependencies.
|
||||
For COLLADA support, you will also have to install the \code{collada-dom}
|
||||
library. For this, you can either install the binary package available on
|
||||
the Mitsuba website, or you can compile it yourself using the \code{PKGBUILD}
|
||||
supplied with Mitsuba, i.e.
|
||||
\begin{shell}
|
||||
$\text{\$}$ mkdir packer && cd packer
|
||||
$\text{\$}$ wget http://aur.archlinux.org/packages/packer/packer/PKGBUILD
|
||||
$\text{\$}$ makepkg -is
|
||||
$\text{\$}$ cd <some-temporary-directory>
|
||||
$\text{\$}$ cp <path-to-mitsuba>/data/linux/arch/collada-dom/PKGBUILD .
|
||||
$\text{\$}$ makepkg PKGBUILD
|
||||
<..compiling..>
|
||||
$\text{\$}$ sudo pacman -U <generated package file>
|
||||
\end{shell}
|
||||
|
||||
Next, use packer to automatically download, build, and install Mitsuba as well as any needed dependencies.
|
||||
The optional \code{--noedit} flag is used if you do not wish to edit the files after they are downloaded.
|
||||
The optional \code{--noconfirm} flag is used if you do not wish to confirm each step of the installation.
|
||||
Once all dependencies are taken care of, simply run
|
||||
\begin{shell}
|
||||
$\text{\$}$ sudo packer -S --noedit --noconfirm mitsuba-hg glewmx collada-dom
|
||||
$\text{\$}$ scons
|
||||
\end{shell}
|
||||
|
||||
Periodically you may wish to update Mitsuba to the latest version.
|
||||
To do this simply reinstall it and packer will pull and build the latest version.
|
||||
inside the Mitsuba directory. In the case that you have multiple processors, you might want to parallelize the build by appending \code{-j }\emph{core count} to the command.
|
||||
If all goes well, SCons should finish successfully within a few minutes:
|
||||
\begin{shell}
|
||||
$\text{\$}$ sudo packer -S --noedit --noconfirm mitsuba-hg
|
||||
scons: $\texttt{done}$ building targets.
|
||||
\end{shell}
|
||||
|
||||
Alternatively you can skip using packer and manually download the files and install them one at a time yourself.
|
||||
First install glewmx
|
||||
To be able to run the renderer from the command line, you will first have to import it into your path:
|
||||
\begin{shell}
|
||||
$\text{\$}$ mkdir glewmx && cd glewmx
|
||||
$\text{\$}$ wget http://aur.archlinux.org/packages/glewmx/glewmx/PKGBUILD
|
||||
$\text{\$}$ makepkg -is
|
||||
$\text{\$}$ . setpath.sh
|
||||
\end{shell}
|
||||
|
||||
And then collada-dom
|
||||
\begin{shell}
|
||||
$\text{\$}$ mkdir collada-dom && cd collada-dom
|
||||
$\text{\$}$ wget http://aur.archlinux.org/packages/collada-dom/collada-dom/PKGBUILD
|
||||
$\text{\$}$ makepkg -is
|
||||
\end{shell}
|
||||
|
||||
And finally Mitsuba
|
||||
\begin{shell}
|
||||
$\text{\$}$ mkdir mitsuba-hg && cd mitsuba-hg
|
||||
$\text{\$}$ wget http://aur.archlinux.org/packages/mitsuba-hg/mitsuba-hg/PKGBUILD
|
||||
$\text{\$}$ makepkg -is
|
||||
\end{shell}
|
||||
|
||||
To uninstall do this
|
||||
\begin{shell}
|
||||
$\text{\$}$ sudo pacman -R mitsuba-hg glewmx collada-dom
|
||||
\end{shell}
|
||||
After installing you will be able to run the renderer from the command line.
|
||||
(note the period at the beginning -- this assumes that you are using \code{bash}).
|
||||
Having set up everything, you can now move on to \secref{basics}.
|
||||
|
||||
If for some reason you are unable access the Aur files, they are also hosted at
|
||||
(\url{https://www.mitsuba-renderer.org/releases/contrib/archlinux/}).
|
||||
\subsubsection{Creating Arch Linux packages}
|
||||
Mitsuba ships with a \code{PKGBUILD} file, which automatically builds
|
||||
a package from the most recent repository version:
|
||||
\begin{shell}
|
||||
$\text{\$}$ makepkg data/linux/arch/mitsuba/PKGBUILD
|
||||
\end{shell}
|
||||
|
||||
\subsection{Building on Windows}
|
||||
On the Windows platform, Mitsuba already includes most of the dependencies in precompiled form.
|
||||
|
|
|
@ -39,4 +39,41 @@ print(myVector * 2)
|
|||
Log(EInfo, "" +)
|
||||
\end{python}
|
||||
|
||||
\subsection{Taking control of the logging system}
|
||||
Many operations in Mitsuba will print one or more log messages
|
||||
during their execution. By default, they will be printed to the console,
|
||||
which may be undesirable. Similar to the C++ side, it is possible to define
|
||||
custom \code{Formatter} and \code{Appender} classes to interpret and direct
|
||||
the flow of these messages.
|
||||
|
||||
Roughly, a \code{Formatter} turns detailed
|
||||
information about a logging event into a human-readable string, and a
|
||||
\code{Appender} routes it to some destination (e.g. by appending it to
|
||||
a file or a log viewer in a graphical user interface). Here is an example
|
||||
of how to activate such extensions:
|
||||
\begin{python}
|
||||
import mitsuba
|
||||
from mitsuba.core import *
|
||||
|
||||
class MyFormatter(Formatter):
|
||||
def format(self, logLevel, sourceClass, sourceThread, message, filename, line):
|
||||
return "%s (log level: %s, thread: %s, class %s, file %s, line %i)" % \
|
||||
(message, str(logLevel), sourceThread.getName(), sourceClass,
|
||||
filename, line)
|
||||
|
||||
class MyAppender(Appender):
|
||||
def append(self, logLevel, message):
|
||||
print(message)
|
||||
|
||||
def logProgress(self, progress, name, formatted, eta):
|
||||
print("Progress message: " + formatted)
|
||||
|
||||
# Get the logger associated with the current thread
|
||||
logger = Thread.getThread().getLogger()
|
||||
logger.setFormatter(MyFormatter())
|
||||
logger.clearAppenders()
|
||||
logger.addAppender(MyAppender())
|
||||
logger.setLogLevel(EDebug)
|
||||
|
||||
Log(EInfo, "Test message")
|
||||
\end{python}
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
void save(EFileFormat format, Stream *stream, int compression = 5) const;
|
||||
|
||||
/// Return the image's title identifier
|
||||
inline const std::string &getTile() const { return m_title; }
|
||||
inline const std::string &getTitle() const { return m_title; }
|
||||
|
||||
/// Return the image's author identifier
|
||||
inline const std::string &getAuthor() const { return m_author; }
|
||||
|
@ -90,16 +90,28 @@ public:
|
|||
/// Set the image's gamma identifier (-1: sRGB)
|
||||
inline void setGamma(Float gamma) { m_gamma = gamma; }
|
||||
|
||||
/// Access the underlying raster
|
||||
/**
|
||||
* \brief Access the underlying raster
|
||||
* \remark This function is not exposed in the Python bindings
|
||||
*/
|
||||
inline unsigned char *getData() { return m_data; }
|
||||
|
||||
/// Access the underlying bit raster
|
||||
/**
|
||||
* \brief Access the underlying raster
|
||||
* \remark This function is not exposed in the Python bindings
|
||||
*/
|
||||
inline const unsigned char *getData() const { return m_data; }
|
||||
|
||||
/// Access the underlying raster (only meant for 128bpp images)
|
||||
/**
|
||||
* \brief Access the underlying raster (128bpp images)
|
||||
* \remark This function is not exposed in the Python bindings
|
||||
*/
|
||||
inline float *getFloatData() { return (float *) m_data; }
|
||||
|
||||
/// Access the underlying raster (only meant for 128bpp images)
|
||||
/**
|
||||
* \brief Access the underlying raster (128bpp images)
|
||||
* \remark This function is not exposed in the Python bindings
|
||||
*/
|
||||
inline const float *getFloatData() const { return (const float *) m_data; }
|
||||
|
||||
/// Return the bitmap width
|
||||
|
|
|
@ -24,7 +24,6 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \headerfile mitsuba/core/class.h mitsuba/mitsuba.h
|
||||
* \brief Stores meta-information about \ref Object instances.
|
||||
* \ingroup libcore
|
||||
*
|
||||
* This class provides a thin layer of RTTI (run-time type information),
|
||||
* which is useful for doing things like:
|
||||
|
@ -37,6 +36,8 @@ MTS_NAMESPACE_BEGIN
|
|||
* </ul>
|
||||
*
|
||||
* \sa ref, Object
|
||||
* \ingroup libcore
|
||||
* \ingroup librender
|
||||
*/
|
||||
class MTS_EXPORT_CORE Class {
|
||||
public:
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
*
|
||||
* In comparison to \ref resolve(), this funtion returns all
|
||||
* matches instead of only the first one.
|
||||
*
|
||||
* \remark This function is not exposed in the Python bindings
|
||||
*/
|
||||
std::vector<fs::path> resolveAll(const fs::path &path) const;
|
||||
|
||||
|
|
|
@ -24,10 +24,12 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* Basic memory pool -- allows repeated allocation & deallocation
|
||||
* of objects of the same type, while attempting to keep them
|
||||
* contiguous in memory and having only minimal interaction with the
|
||||
* underlying allocator.
|
||||
* \brief Basic memory pool for efficient allocation and deallocation
|
||||
* of objects of the same type.
|
||||
*
|
||||
* This class attempts to keep most instances contiguous in memory, while
|
||||
* having only minimal interaction with the underlying allocator.
|
||||
*
|
||||
* \ingroup libcore
|
||||
*/
|
||||
template <typename T> class MemoryPool {
|
||||
|
|
|
@ -122,7 +122,11 @@ public:
|
|||
/// Seed the random generator from another random generator
|
||||
void seed(Random *random);
|
||||
|
||||
/// Seed the random generator from an array
|
||||
/**
|
||||
* \brief Seed the random generator from an array
|
||||
* \remark This function is currently not exposed
|
||||
* by the Python bindings
|
||||
*/
|
||||
void seed(uint64_t *values, uint64_t length);
|
||||
|
||||
/// Return an integer on the [0, 2^63-1]-interval
|
||||
|
@ -142,6 +146,9 @@ public:
|
|||
* given STL container.
|
||||
*
|
||||
* See Knuth, TAoCP Vol. 2 (3rd 3d), Section 3.4.2.
|
||||
*
|
||||
* \remark This function is currently not exposed
|
||||
* by the Python bindings
|
||||
*/
|
||||
template <typename Iterator> void shuffle(Iterator it1, Iterator it2) {
|
||||
for (Iterator it = it2 - 1; it > it1; --it)
|
||||
|
|
|
@ -108,7 +108,13 @@ struct Ray {
|
|||
#endif
|
||||
}
|
||||
|
||||
/// Return 3d coordinates of a point on the ray
|
||||
/**
|
||||
* \brief Return 3D coordinates of a point along the ray
|
||||
*
|
||||
* \remark In the Python bindings, this operator is
|
||||
* exposed as a function named \c eval -- i.e.
|
||||
* position lookups should be written as \c ray.eval(t)
|
||||
*/
|
||||
inline Point operator() (Float t) const { return o + t * d; }
|
||||
|
||||
/// Return a string representation of this ray
|
||||
|
|
|
@ -86,8 +86,12 @@ std::string FileResolver::toString() const {
|
|||
std::ostringstream oss;
|
||||
oss << "FileResolver[" << endl
|
||||
<< " paths = {" << endl;
|
||||
for (size_t i=0; i<m_paths.size(); ++i)
|
||||
oss << " \"" << m_paths[i].file_string() << "\"," << endl;
|
||||
for (size_t i=0; i<m_paths.size(); ++i) {
|
||||
oss << " \"" << m_paths[i].file_string() << "\"";
|
||||
if (i+1 < m_paths.size())
|
||||
oss << ",";
|
||||
oss << endl;
|
||||
}
|
||||
oss << " }" << endl
|
||||
<< "]";
|
||||
return oss.str();
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <mitsuba/core/transform.h>
|
||||
#include <mitsuba/core/properties.h>
|
||||
#include <mitsuba/core/appender.h>
|
||||
#include <mitsuba/core/bitmap.h>
|
||||
#include <mitsuba/core/random.h>
|
||||
|
||||
using namespace mitsuba;
|
||||
|
||||
|
@ -140,6 +142,18 @@ static Float Matrix4x4_getItem(Matrix4x4 *matrix, bp::tuple tuple) {
|
|||
return matrix->operator()(i, j);
|
||||
}
|
||||
|
||||
Class *object_getClass(Object *object) {
|
||||
return const_cast<Class *>(object->getClass());
|
||||
}
|
||||
|
||||
Class *class_forName(const char *name) {
|
||||
return const_cast<Class *>(Class::forName(name));
|
||||
}
|
||||
|
||||
Class *class_getSuperClass(Class *theClass) {
|
||||
return const_cast<Class *>(theClass->getSuperClass());
|
||||
}
|
||||
|
||||
static ref<SerializableObject> instance_manager_getinstance(InstanceManager *manager, Stream *stream) {
|
||||
return manager->getInstance(stream);
|
||||
}
|
||||
|
@ -167,6 +181,25 @@ void mts_log(ELogLevel level, const std::string &msg) {
|
|||
msg.c_str());
|
||||
}
|
||||
|
||||
class FormatterWrapper : public Formatter {
|
||||
public:
|
||||
FormatterWrapper(PyObject *self) : m_self(self) { Py_INCREF(m_self); }
|
||||
|
||||
std::string format(ELogLevel logLevel, const Class *theClass,
|
||||
const Thread *thread, const std::string &text,
|
||||
const char *file, int line) {
|
||||
return bp::call_method<std::string>(m_self, "format", logLevel,
|
||||
bp::ptr(const_cast<Class *>(theClass)),
|
||||
bp::ptr(const_cast<Thread *>(thread)), text, file, line);
|
||||
}
|
||||
|
||||
virtual ~FormatterWrapper() {
|
||||
Py_DECREF(m_self);
|
||||
}
|
||||
private:
|
||||
PyObject *m_self;
|
||||
};
|
||||
|
||||
class AppenderWrapper : public Appender {
|
||||
public:
|
||||
AppenderWrapper(PyObject *self) : m_self(self) { Py_INCREF(m_self); }
|
||||
|
@ -199,12 +232,16 @@ static Spectrum *spectrum_array_constructor(bp::list list) {
|
|||
return new Spectrum(spec);
|
||||
}
|
||||
|
||||
static Point ray_eval(const Ray &ray, Float t) {
|
||||
return ray(t);
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fromLinearRGB_overloads, fromLinearRGB, 3, 4)
|
||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fromXYZ_overloads, fromXYZ, 3, 4)
|
||||
|
||||
void export_core() {
|
||||
boost::python::to_python_converter<
|
||||
fs::path, path_to_python_str>();
|
||||
bp::to_python_converter<fs::path, path_to_python_str>();
|
||||
bp::implicitly_convertible<std::string, fs::path>();
|
||||
|
||||
bp::object coreModule(
|
||||
bp::handle<>(bp::borrowed(PyImport_AddModule("mitsuba.core"))));
|
||||
|
@ -223,8 +260,22 @@ void export_core() {
|
|||
|
||||
bp::def("Log", &mts_log);
|
||||
|
||||
bp::class_<Class, boost::noncopyable>("Class", bp::no_init)
|
||||
.def("getName", &Class::getName, BP_RETURN_CONSTREF)
|
||||
.def("isAbstract", &Class::isAbstract)
|
||||
.def("isInstantiable", &Class::isInstantiable)
|
||||
.def("isSerializable", &Class::isSerializable)
|
||||
.def("derivesFrom", &Class::derivesFrom)
|
||||
.def("getSuperClass", &class_getSuperClass, BP_RETURN_INTREF)
|
||||
.def("forName", &class_forName, BP_RETURN_INTREF)
|
||||
.def("unserialize", &Class::unserialize, BP_RETURN_VALUE)
|
||||
.def("instantiate", &Class::instantiate, BP_RETURN_VALUE)
|
||||
.staticmethod("forName");
|
||||
bp::register_ptr_to_python<Class*>();
|
||||
|
||||
bp::class_<Object, ref<Object>, boost::noncopyable>("Object", bp::no_init)
|
||||
.def("getRefCount", &Object::getRefCount)
|
||||
.def("getClass", &object_getClass, BP_RETURN_INTREF)
|
||||
.def("__str__", &Object::toString);
|
||||
bp::register_ptr_to_python<Object*>();
|
||||
|
||||
|
@ -338,6 +389,9 @@ void export_core() {
|
|||
.def("append", &Appender::append)
|
||||
.def("logProgress", &appender_logProgress);
|
||||
|
||||
BP_WRAPPED_CLASS(Formatter, FormatterWrapper, Object, bp::init<>())
|
||||
.def("format", &Formatter::format);
|
||||
|
||||
Appender *(Logger::*logger_get_appender)(size_t) = &Logger::getAppender;
|
||||
BP_CLASS(Logger, Object, bp::init<ELogLevel>())
|
||||
.def("logProgress", logger_logProgress)
|
||||
|
@ -350,6 +404,8 @@ void export_core() {
|
|||
.def("clearAppenders", &Logger::clearAppenders)
|
||||
.def("getAppenderCount", &Logger::getAppenderCount)
|
||||
.def("getAppender", logger_get_appender, BP_RETURN_VALUE)
|
||||
.def("getFormatter", &Logger::getFormatter, BP_RETURN_VALUE)
|
||||
.def("setFormatter", &Logger::setFormatter)
|
||||
.def("getWarningCount", &Logger::getWarningCount);
|
||||
|
||||
BP_CLASS(InstanceManager, Object, bp::init<>())
|
||||
|
@ -369,6 +425,56 @@ void export_core() {
|
|||
.def("clear", &InterpolatedSpectrum::clear)
|
||||
.def("zeroExtend", &InterpolatedSpectrum::zeroExtend);
|
||||
|
||||
BP_CLASS(Bitmap, Object, (bp::init<int, int, int>()))
|
||||
.def(bp::init<Bitmap::EFileFormat, Stream *>())
|
||||
.def("clone", &Bitmap::clone, BP_RETURN_VALUE)
|
||||
.def("clear", &Bitmap::clear)
|
||||
.def("save", &Bitmap::save)
|
||||
.def("setTitle", &Bitmap::setTitle)
|
||||
.def("getTitle", &Bitmap::getTitle, BP_RETURN_INTREF)
|
||||
.def("setAuthor", &Bitmap::setAuthor)
|
||||
.def("getAuthor", &Bitmap::getAuthor, BP_RETURN_INTREF)
|
||||
.def("setComment", &Bitmap::setComment)
|
||||
.def("getComment", &Bitmap::getComment, BP_RETURN_INTREF)
|
||||
.def("setGamma", &Bitmap::setGamma)
|
||||
.def("getGamma", &Bitmap::getGamma)
|
||||
.def("getWidth", &Bitmap::getWidth)
|
||||
.def("getHeight", &Bitmap::getHeight)
|
||||
.def("getBitsPerPixel", &Bitmap::getBitsPerPixel)
|
||||
.def("getSize", &Bitmap::getSize);
|
||||
|
||||
BP_SETSCOPE(Bitmap_class);
|
||||
bp::enum_<Bitmap::EFileFormat>("EFileFormat")
|
||||
.value("EPNG", Bitmap::EPNG)
|
||||
.value("EEXR", Bitmap::EEXR)
|
||||
.value("ETGA", Bitmap::ETGA)
|
||||
.value("EBMP", Bitmap::EBMP)
|
||||
.value("EJPEG", Bitmap::EJPEG)
|
||||
.export_values();
|
||||
BP_SETSCOPE(coreModule);
|
||||
|
||||
BP_CLASS(FileResolver, Object, bp::init<>())
|
||||
.def("resolve", &FileResolver::resolve, BP_RETURN_VALUE)
|
||||
.def("resolveAbsolute", &FileResolver::resolveAbsolute, BP_RETURN_VALUE)
|
||||
.def("clone", &FileResolver::clone, BP_RETURN_VALUE)
|
||||
.def("addPath", &FileResolver::addPath)
|
||||
.def("clear", &FileResolver::clear);
|
||||
|
||||
void (Random::*random_seed_random)(Random *) = &Random::seed;
|
||||
void (Random::*random_seed_uint64_t)(uint64_t) = &Random::seed;
|
||||
BP_CLASS(Random, Object, bp::init<>())
|
||||
.def(bp::init<uint64_t>())
|
||||
.def(bp::init<Random *>())
|
||||
.def(bp::init<Stream *, InstanceManager *>())
|
||||
.def("set", &Random::set)
|
||||
.def("seed", random_seed_random)
|
||||
.def("seed", random_seed_uint64_t)
|
||||
.def("nextULong", &Random::nextULong)
|
||||
.def("nextUInt", &Random::nextUInt)
|
||||
.def("nextSize", &Random::nextSize)
|
||||
.def("nextFloat", &Random::nextFloat)
|
||||
.def("serialize", &Random::serialize);
|
||||
|
||||
BP_STRUCT(Spectrum, bp::init<>())
|
||||
.def("__init__", bp::make_constructor(spectrum_array_constructor))
|
||||
.def(bp::init<Float>())
|
||||
|
@ -610,6 +716,23 @@ void export_core() {
|
|||
.def(bp::self /= Float())
|
||||
.def("__str__", &Matrix4x4::toString);
|
||||
|
||||
bp::class_<Ray>("Ray", bp::init<>())
|
||||
.def(bp::init<Ray &>())
|
||||
.def(bp::init<Ray &, Float, Float>())
|
||||
.def(bp::init<Point, Vector, Float>())
|
||||
.def(bp::init<Point, Vector, Float, Float, Float>())
|
||||
.def_readwrite("o", &Ray::o)
|
||||
.def_readwrite("d", &Ray::d)
|
||||
.def_readwrite("dRcp", &Ray::dRcp)
|
||||
.def_readwrite("mint", &Ray::mint)
|
||||
.def_readwrite("maxt", &Ray::maxt)
|
||||
.def_readwrite("time", &Ray::time)
|
||||
.def("setOrigin", &Ray::setOrigin)
|
||||
.def("setDirection", &Ray::setDirection)
|
||||
.def("setTime", &Ray::setTime)
|
||||
.def("eval", &ray_eval, BP_RETURN_VALUE)
|
||||
.def("__str__", &Ray::toString);
|
||||
|
||||
bp::detail::current_scope = oldScope;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue