done with the python integration (for now)
parent
38b1337788
commit
94fd78d0a5
|
@ -190,6 +190,7 @@ might start the with parameters such as the following
|
||||||
$\texttt{\$}$ mitsuba -xj 2 -c machine1;machine2;... animation/frame_*.xml
|
$\texttt{\$}$ mitsuba -xj 2 -c machine1;machine2;... animation/frame_*.xml
|
||||||
\end{shell}
|
\end{shell}
|
||||||
\subsection{Direct connection server}
|
\subsection{Direct connection server}
|
||||||
|
\label{sec:mtssrv}
|
||||||
A Mitsuba compute node can be created using the \code{mtssrv} executable. By default,
|
A Mitsuba compute node can be created using the \code{mtssrv} executable. By default,
|
||||||
it will listen on port 7554:
|
it will listen on port 7554:
|
||||||
\begin{shell}
|
\begin{shell}
|
||||||
|
|
|
@ -8,7 +8,7 @@ software construction tool. There are some differences between the different ope
|
||||||
more details, please refer to one of the next sections depending on which one you use.
|
more details, please refer to one of the next sections depending on which one you use.
|
||||||
|
|
||||||
\subsection{Common steps}
|
\subsection{Common steps}
|
||||||
To get started, you will need to download a recent version of Mitsuba. Make sure that you have the Mercurial (\url{http://mercurial.selenic.com/}) versioning system installed\footnote{On Windows, you might also want the convenient TortoiseHG shell extension (\url{http://tortoisehg.bitbucket.org/}) to run the subsequent steps directly from the Explorer.} and enter the following at the command prompt:
|
To get started, you will need to download a recent version of Mitsuba. Make sure that you have the Mercurial (\url{http://mercurial.selenic.com/}) versioning system installed\footnote{On Windows, you might want to use the convenient TortoiseHG shell extension (\url{http://tortoisehg.bitbucket.org/}) to run the subsequent steps directly from the Explorer.} and enter the following at the command prompt:
|
||||||
\begin{shell}
|
\begin{shell}
|
||||||
$\texttt{\$}$ hg clone https://www.mitsuba-renderer.org/hg/mitsuba
|
$\texttt{\$}$ hg clone https://www.mitsuba-renderer.org/hg/mitsuba
|
||||||
\end{shell}
|
\end{shell}
|
||||||
|
@ -199,7 +199,7 @@ $\text{\$}$ rpmbuild -bb mitsuba-$\code{\MitsubaVersion}$/data/linux/fedora/mits
|
||||||
\end{shell}
|
\end{shell}
|
||||||
After this command finishes, its output can be found in the directory \code{rpmbuild/RPMS}.
|
After this command finishes, its output can be found in the directory \code{rpmbuild/RPMS}.
|
||||||
\subsection{Building on Arch Linux}
|
\subsection{Building on Arch Linux}
|
||||||
You'll first need to install a number of dependencies: run
|
You'll first need to install a number of dependencies:
|
||||||
\begin{shell}
|
\begin{shell}
|
||||||
$\text{\$}$ sudo pacman -S gcc xerces-c glew openexr boost libpng libjpeg qt scons mercurial python
|
$\text{\$}$ sudo pacman -S gcc xerces-c glew openexr boost libpng libjpeg qt scons mercurial python
|
||||||
\end{shell}
|
\end{shell}
|
||||||
|
|
|
@ -81,6 +81,8 @@
|
||||||
% Listings settings
|
% Listings settings
|
||||||
\lstset{
|
\lstset{
|
||||||
basicstyle = \small\ttfamily\raggedright,
|
basicstyle = \small\ttfamily\raggedright,
|
||||||
|
commentstyle=\color{lstcomment}\itshape,
|
||||||
|
stringstyle=\color{lstattrib},
|
||||||
mathescape = true,
|
mathescape = true,
|
||||||
frame = lrtb,
|
frame = lrtb,
|
||||||
backgroundcolor = \color{lstshade},
|
backgroundcolor = \color{lstshade},
|
||||||
|
@ -111,6 +113,7 @@
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
% Set up textpos
|
% Set up textpos
|
||||||
\TPGrid{68}{108}
|
\TPGrid{68}{108}
|
||||||
|
|
||||||
|
@ -125,7 +128,7 @@
|
||||||
{}
|
{}
|
||||||
\lstnewenvironment{cpp}[1][]{\lstset{language=c++, #1}}
|
\lstnewenvironment{cpp}[1][]{\lstset{language=c++, #1}}
|
||||||
{}
|
{}
|
||||||
\lstnewenvironment{python}[1][]{\lstset{language=python, #1}}
|
\lstnewenvironment{python}[1][]{\lstset{language=Python, #1}}
|
||||||
{}
|
{}
|
||||||
\lstnewenvironment{xml}[1][]{\lstset{language=xml, #1}}
|
\lstnewenvironment{xml}[1][]{\lstset{language=xml, #1}}
|
||||||
{}
|
{}
|
||||||
|
@ -156,8 +159,8 @@
|
||||||
\IfFileExists{plugins_generated.tex}{\include{plugins_generated}}{}
|
\IfFileExists{plugins_generated.tex}{\include{plugins_generated}}{}
|
||||||
%\include{import}
|
%\include{import}
|
||||||
\include{development}
|
\include{development}
|
||||||
%\include{integrator}
|
\include{integrator}
|
||||||
%\include{parallelization}
|
\include{parallelization}
|
||||||
\include{python}
|
\include{python}
|
||||||
\include{acknowledgements}
|
\include{acknowledgements}
|
||||||
|
|
||||||
|
|
242
doc/python.tex
242
doc/python.tex
|
@ -2,7 +2,7 @@
|
||||||
\label{sec:python}
|
\label{sec:python}
|
||||||
A recent feature of Mitsuba is a simple Python interface to the renderer API.
|
A recent feature of Mitsuba is a simple Python interface to the renderer API.
|
||||||
While the interface is still limited at this point, it can already be
|
While the interface is still limited at this point, it can already be
|
||||||
used for simple automation purposes. To access the API, start your Python
|
used for many useful purposes. To access the API, start your Python
|
||||||
interpreter and enter
|
interpreter and enter
|
||||||
\begin{python}
|
\begin{python}
|
||||||
import mitsuba
|
import mitsuba
|
||||||
|
@ -10,7 +10,7 @@ import mitsuba
|
||||||
For this to work on MacOS X, you will first have to run the ``\emph{Apple
|
For this to work on MacOS X, you will first have to run the ``\emph{Apple
|
||||||
Menu}$\to$\emph{Command-line access}'' menu item from within Mitsuba.
|
Menu}$\to$\emph{Command-line access}'' menu item from within Mitsuba.
|
||||||
On Windows and non-packaged Linux builds, you may have to update the extension
|
On Windows and non-packaged Linux builds, you may have to update the extension
|
||||||
search path before issuing the \code{import} command:
|
search path before issuing the \code{import} command, e.g.:
|
||||||
\begin{python}
|
\begin{python}
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
@ -20,26 +20,242 @@ sys.path.append('dist/python')
|
||||||
|
|
||||||
import mitsuba
|
import mitsuba
|
||||||
\end{python}
|
\end{python}
|
||||||
For an overview of the currently exposed API subset, refer
|
For an overview of the currently exposed API subset, please refer
|
||||||
to the following page: \url{http://www.mitsuba-renderer.org/api/group__libpython.html}.
|
to the following page: \url{http://www.mitsuba-renderer.org/api/group__libpython.html}.
|
||||||
|
|
||||||
\subsection{Fundamentals}
|
\subsection{Basics}
|
||||||
All
|
Generally, the Python API tries to mimic the C++ API as closely as possible.
|
||||||
|
Where applicable, the Python classes and methods replicate overloaded operators,
|
||||||
|
overridable virtual function calls, and default arguments. Under rare circumstances,
|
||||||
|
some features are inherently non-portable due to fundamental differences between the
|
||||||
|
two programming languages. In this case, the API documentation will contain further
|
||||||
|
information.
|
||||||
|
|
||||||
Where applicable, the Python wrapper supports operator overloading,
|
Mitsuba's linear algebra-related classes are usable with essentially the
|
||||||
default arguments, and
|
same syntax as their C++ versions --- for example, the following snippet
|
||||||
|
creates and rotates a unit vector.
|
||||||
\begin{python}
|
\begin{python}
|
||||||
import mitsuba
|
import mitsuba
|
||||||
from mitsuba.core import *
|
from mitsuba.core import *
|
||||||
|
|
||||||
|
# Create a normalized direction vector
|
||||||
myVector = normalize(Vector(1.0, 2.0, 3.0))
|
myVector = normalize(Vector(1.0, 2.0, 3.0))
|
||||||
|
|
||||||
print(myVector * 2)
|
# 90 deg. rotation around the Y axis
|
||||||
|
trafo = Transform.rotate(Vector(0, 1, 0), 90)
|
||||||
|
|
||||||
Log(EInfo, "" +)
|
# Apply the rotation and display the result
|
||||||
|
print(trafo * myVector)
|
||||||
\end{python}
|
\end{python}
|
||||||
|
|
||||||
\subsection{Taking control of the logging system}
|
\subsection{Recipes}
|
||||||
|
The following section contains a series of ``recipes'' on how to do
|
||||||
|
certain things with the help of the Python bindings.
|
||||||
|
|
||||||
|
\subsubsection{Loading a scene}
|
||||||
|
The following script demonstrates how to use the
|
||||||
|
\code{FileResolver} and \code{SceneHandler} classes to
|
||||||
|
load a Mitsuba scene from an XML file:
|
||||||
|
\begin{python}
|
||||||
|
import mitsuba
|
||||||
|
|
||||||
|
from mitsuba.core import *
|
||||||
|
from mitsuba.render import SceneHandler
|
||||||
|
|
||||||
|
# Get a reference to the thread's file resolver
|
||||||
|
fileResolver = Thread.getThread().getFileResolver()
|
||||||
|
|
||||||
|
# Add the search path needed to load plugins
|
||||||
|
fileResolver.addPath('<path to mitsuba directory>')
|
||||||
|
|
||||||
|
# Add the search path needed to load scene resources
|
||||||
|
fileResolver.addPath('<path to scene directory>')
|
||||||
|
|
||||||
|
# Optional: supply parameters that can be accessed
|
||||||
|
# by the scene (e.g. as $\text{\color{lstcomment}\itshape\texttt{\$}}$myParameter)
|
||||||
|
paramMap = StringMap()
|
||||||
|
paramMap['myParameter'] = 'value'
|
||||||
|
|
||||||
|
# Load the scene from an XML file
|
||||||
|
scene = SceneHandler.loadScene(fileResolver, paramMap)
|
||||||
|
|
||||||
|
# Display a textual summary of the scene's contents
|
||||||
|
print(scene)
|
||||||
|
\end{python}
|
||||||
|
|
||||||
|
\subsubsection{Rendering a loaded scene}
|
||||||
|
Once a scene has been loaded, it can be rendered as follows:
|
||||||
|
\begin{python}
|
||||||
|
from mitsuba.core import *
|
||||||
|
from mitsuba.render import RenderQueue, RenderJob
|
||||||
|
import multiprocessing
|
||||||
|
|
||||||
|
scheduler = Scheduler.getInstance()
|
||||||
|
|
||||||
|
# Start up the scheduling system with one worker per local core
|
||||||
|
for i in range(0, multiprocessing.cpu_count()):
|
||||||
|
scheduler.registerWorker(LocalWorker('wrk%i' % i))
|
||||||
|
scheduler.start()
|
||||||
|
|
||||||
|
# Create a queue for tracking render jobs
|
||||||
|
queue = RenderQueue()
|
||||||
|
|
||||||
|
scene.setDestinationFile('renderedResult')
|
||||||
|
|
||||||
|
# Create a render job and insert it into the queue
|
||||||
|
job = RenderJob('myRenderJob', scene, queue)
|
||||||
|
job.start()
|
||||||
|
|
||||||
|
# Wait for all jobs to finish and release resources
|
||||||
|
queue.waitLeft(0)
|
||||||
|
queue.join()
|
||||||
|
|
||||||
|
# Print some statistics about the rendering process
|
||||||
|
print(Statistics.getInstance().getStats())
|
||||||
|
\end{python}
|
||||||
|
|
||||||
|
\subsubsection{Rendering over the network}
|
||||||
|
To render over the network, you must first set up one or
|
||||||
|
more machines that run the \code{mtssrv} server (see \secref{mtssrv}).
|
||||||
|
A network node can then be registered with the scheduler as follows:
|
||||||
|
\begin{python}
|
||||||
|
# Connect to a socket on a named host or IP address
|
||||||
|
# 7554 is the default port of 'mtssrv'
|
||||||
|
stream = SocketStream('128.84.103.222', 7554)
|
||||||
|
|
||||||
|
# Create a remote worker instance that communicates over the stream
|
||||||
|
remoteWorker = RemoteWorker('netWorker', stream)
|
||||||
|
|
||||||
|
scheduler = Scheduler.getInstance()
|
||||||
|
# Register the remote worker (and any other potential workers)
|
||||||
|
scheduler.registerWorker(remoteWorker)
|
||||||
|
scheduler.start()
|
||||||
|
\end{python}
|
||||||
|
|
||||||
|
\subsubsection{Constructing custom scenes from Python}
|
||||||
|
Dynamically constructing Mitsuba scenes entails loading a series of external
|
||||||
|
plugins, instantiating them with custom parameters, and finally assembling
|
||||||
|
them into an object graph.
|
||||||
|
For instance, the following snippet shows how to create a basic
|
||||||
|
perspective camera with a film that writes PNG images:
|
||||||
|
\begin{python}
|
||||||
|
from mitsuba.core import *
|
||||||
|
pmgr = PluginManager.getInstance()
|
||||||
|
|
||||||
|
# Encodes parameters on how to instantiate the 'perspective' plugin
|
||||||
|
cameraProps = Properties('perspective')
|
||||||
|
cameraProps['toWorld'] = Transform.lookAt(
|
||||||
|
Point(0, 0, -10), # Camera origin
|
||||||
|
Point(0, 0, 0), # Camera target
|
||||||
|
Vector(0, 1, 0) # 'up' vector
|
||||||
|
)
|
||||||
|
cameraProps['fov'] = 45.0
|
||||||
|
|
||||||
|
# Encodes parameters on how to instantiate the 'pngfilm' plugin
|
||||||
|
filmProps = Properties('pngfilm')
|
||||||
|
filmProps['width'] = 1920
|
||||||
|
filmProps['height'] = 1080
|
||||||
|
|
||||||
|
# Load and instantiate the plugins
|
||||||
|
camera = pmgr.createObject(cameraProps)
|
||||||
|
film = pmgr.createObject(filmProps)
|
||||||
|
|
||||||
|
# First configure the film and then add it to the camera
|
||||||
|
film.configure()
|
||||||
|
camera.addChild('film', film)
|
||||||
|
|
||||||
|
# Now, the camera can be configured
|
||||||
|
camera.configure()
|
||||||
|
\end{python}
|
||||||
|
The above code fragment uses the plugin manager to construct a
|
||||||
|
\code{Camera} instance from an external plugin named
|
||||||
|
\texttt{perspective.so/dll/dylib} and adds a child object
|
||||||
|
named \texttt{film}, which is a \texttt{Film} instance loaded from the
|
||||||
|
plugin \texttt{pngfilm.so/dll/dylib}.
|
||||||
|
Each time after instantiating a plugin, all child objects are added, and
|
||||||
|
finally the plugin's \code{configure()} method must be called.
|
||||||
|
|
||||||
|
Creating scenes in this manner ends up being rather laborious.
|
||||||
|
Since Python comes with a powerful dynamically-typed dictionary
|
||||||
|
primitive, Mitsuba additionally provides a more ``pythonic''
|
||||||
|
alternative that makes use of this facility:
|
||||||
|
\begin{python}
|
||||||
|
from mitsuba.core import *
|
||||||
|
|
||||||
|
pmgr = PluginManager.getInstance()
|
||||||
|
camera = pmgr.create({
|
||||||
|
'type' : 'perspective',
|
||||||
|
'toWorld' : Transform.lookAt(
|
||||||
|
Point(0, 0, -10),
|
||||||
|
Point(0, 0, 0),
|
||||||
|
Vector(0, 1, 0)
|
||||||
|
),
|
||||||
|
'film' : {
|
||||||
|
'type' : 'pngfilm',
|
||||||
|
'width' : 1920,
|
||||||
|
'height' : 1080
|
||||||
|
}
|
||||||
|
})
|
||||||
|
\end{python}
|
||||||
|
This code does exactly the same as the previous snippet.
|
||||||
|
By the time \code{PluginManager.create} returns, the object
|
||||||
|
hierarchy has already been assembled, and the
|
||||||
|
\code{configure()} method of every object
|
||||||
|
has been called.
|
||||||
|
|
||||||
|
Finally, here is an full example that creates a basic scene
|
||||||
|
which can be rendered. It describes a sphere lit by a point
|
||||||
|
light, rendered using the direct illumination integrator.
|
||||||
|
\begin{python}
|
||||||
|
from mitsuba.core import *
|
||||||
|
from mitsuba.render import Scene
|
||||||
|
|
||||||
|
scene = Scene()
|
||||||
|
|
||||||
|
# Create a camera, film & sample generator
|
||||||
|
scene.addChild(pmgr.create({
|
||||||
|
'type' : 'perspective',
|
||||||
|
'toWorld' : Transform.lookAt(
|
||||||
|
Point(0, 0, -10),
|
||||||
|
Point(0, 0, 0),
|
||||||
|
Vector(0, 1, 0)
|
||||||
|
),
|
||||||
|
'film' : {
|
||||||
|
'type' : 'pngfilm',
|
||||||
|
'width' : 1920,
|
||||||
|
'height' : 1080
|
||||||
|
},
|
||||||
|
'sampler' : {
|
||||||
|
'type' : 'ldsampler',
|
||||||
|
'sampleCount' : 2
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
# Set the integrator
|
||||||
|
scene.addChild(pmgr.create({
|
||||||
|
'type' : 'direct'
|
||||||
|
}))
|
||||||
|
|
||||||
|
# Add a light source
|
||||||
|
scene.addChild(pmgr.create({
|
||||||
|
'type' : 'point',
|
||||||
|
'position' : Point(5, 0, -10),
|
||||||
|
'intensity' : Spectrum(100)
|
||||||
|
}))
|
||||||
|
|
||||||
|
# Add a shape
|
||||||
|
scene.addChild(pmgr.create({
|
||||||
|
'type' : 'sphere',
|
||||||
|
'center' : Point(0, 0, 0),
|
||||||
|
'radius' : 1.0,
|
||||||
|
'bsdf' : {
|
||||||
|
'type' : 'diffuse',
|
||||||
|
'reflectance' : Spectrum(0.4)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
\end{python}
|
||||||
|
|
||||||
|
\subsubsection{Taking control of the logging system}
|
||||||
Many operations in Mitsuba will print one or more log messages
|
Many operations in Mitsuba will print one or more log messages
|
||||||
during their execution. By default, they will be printed to the console,
|
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
|
which may be undesirable. Similar to the C++ side, it is possible to define
|
||||||
|
@ -57,7 +273,7 @@ from mitsuba.core import *
|
||||||
|
|
||||||
class MyFormatter(Formatter):
|
class MyFormatter(Formatter):
|
||||||
def format(self, logLevel, sourceClass, sourceThread, message, filename, line):
|
def format(self, logLevel, sourceClass, sourceThread, message, filename, line):
|
||||||
return "%s (log level: %s, thread: %s, class %s, file %s, line %i)" % \
|
return '%s (log level: %s, thread: %s, class %s, file %s, line %i)' % \
|
||||||
(message, str(logLevel), sourceThread.getName(), sourceClass,
|
(message, str(logLevel), sourceThread.getName(), sourceClass,
|
||||||
filename, line)
|
filename, line)
|
||||||
|
|
||||||
|
@ -66,7 +282,7 @@ class MyAppender(Appender):
|
||||||
print(message)
|
print(message)
|
||||||
|
|
||||||
def logProgress(self, progress, name, formatted, eta):
|
def logProgress(self, progress, name, formatted, eta):
|
||||||
print("Progress message: " + formatted)
|
print('Progress message: ' + formatted)
|
||||||
|
|
||||||
# Get the logger associated with the current thread
|
# Get the logger associated with the current thread
|
||||||
logger = Thread.getThread().getLogger()
|
logger = Thread.getThread().getLogger()
|
||||||
|
@ -75,5 +291,5 @@ logger.clearAppenders()
|
||||||
logger.addAppender(MyAppender())
|
logger.addAppender(MyAppender())
|
||||||
logger.setLogLevel(EDebug)
|
logger.setLogLevel(EDebug)
|
||||||
|
|
||||||
Log(EInfo, "Test message")
|
Log(EInfo, 'Test message')
|
||||||
\end{python}
|
\end{python}
|
||||||
|
|
|
@ -23,13 +23,16 @@
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
/** \brief Abstract interface for objects that reference shared network resources.
|
/** \brief Abstract interface for objects that reference shared network
|
||||||
|
* resources.
|
||||||
*
|
*
|
||||||
* When a networked object is serialized as part of a parallel process executed on
|
* When a networked object is serialized as part of a parallel process
|
||||||
* multiple machines, the object is first given the opportunity to bind named resources
|
* executed on multiple machines, the object is first given the
|
||||||
* to the process (by a call to <tt>\ref bindUsedResources()</tt>). These will then be
|
* opportunity to bind named resources to the process (by a call to
|
||||||
* distributed to all participating compute servers. Once unserialized on the remote side,
|
* \ref bindUsedResources()). These will then be distributed to all
|
||||||
* <tt>\ref wakeup()</tt> is called to let the object re-associate with the shared resources.
|
* participating compute servers. Once unserialized on the remote side,
|
||||||
|
* \ref wakeup() is called to let the object re-associate with the
|
||||||
|
* shared resources.
|
||||||
*
|
*
|
||||||
* \ingroup libcore
|
* \ingroup libcore
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -30,8 +30,8 @@ MTS_NAMESPACE_BEGIN
|
||||||
* \brief Abstract plugin class -- represents loadable configurable objects
|
* \brief Abstract plugin class -- represents loadable configurable objects
|
||||||
* and utilities.
|
* and utilities.
|
||||||
*
|
*
|
||||||
* Please see the <tt>\ref ConfigurableObject</tt> and
|
* Please see the \ref ConfigurableObject and \ref Utility classes for
|
||||||
* <tt>\ref Utility</tt> classes for details
|
* details.
|
||||||
*
|
*
|
||||||
* \ingroup libcore
|
* \ingroup libcore
|
||||||
*/
|
*/
|
||||||
|
@ -86,6 +86,44 @@ private:
|
||||||
* \brief The plugin manager is responsible for resolving and
|
* \brief The plugin manager is responsible for resolving and
|
||||||
* loading external plugins.
|
* loading external plugins.
|
||||||
*
|
*
|
||||||
|
* Ordinarily, this class will be used by making repeated calls to
|
||||||
|
* the \ref createObject() methods. The generated instances are then
|
||||||
|
* assembled into a final object graph, such as a scene. One such
|
||||||
|
* examples is the \ref SceneHandler class, which parses an XML
|
||||||
|
* scene file by esentially translating the XML elements into calls
|
||||||
|
* to \ref createObject().
|
||||||
|
*
|
||||||
|
* Since this kind of construction method can be tiresome when
|
||||||
|
* dynamically building scenes from Python, this class has an
|
||||||
|
* additional Python-only method \c create(), which works as follows:
|
||||||
|
*
|
||||||
|
* \code
|
||||||
|
* from mitsuba.core import *
|
||||||
|
*
|
||||||
|
* pmgr = PluginManager.getInstance()
|
||||||
|
* camera = pmgr.create({
|
||||||
|
* "type" : "perspective",
|
||||||
|
* "toWorld" : Transform.lookAt(
|
||||||
|
* Point(0, 0, -10),
|
||||||
|
* Point(0, 0, 0),
|
||||||
|
* Vector(0, 1, 0)
|
||||||
|
* ),
|
||||||
|
* "film" : {
|
||||||
|
* "type" : "pngfilm",
|
||||||
|
* "width" : 1920,
|
||||||
|
* "height" : 1080
|
||||||
|
* }
|
||||||
|
* })
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* The above snippet constructs a \ref Camera instance from a
|
||||||
|
* plugin named \c perspective.so/dll/dylib and adds a child object
|
||||||
|
* named \c film, which is a \ref Film instance loaded from the
|
||||||
|
* plugin \c pngfilm.so/dll/dylib. By the time the function
|
||||||
|
* returns, the object hierarchy has already been assembled, and the
|
||||||
|
* \ref ConfigurableObject::configure() methods of every object
|
||||||
|
* has been called.
|
||||||
|
*
|
||||||
* \ingroup libcore
|
* \ingroup libcore
|
||||||
* \ingroup libpython
|
* \ingroup libpython
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -340,10 +340,10 @@ public:
|
||||||
*/
|
*/
|
||||||
static void rotation(const Transform &t, SHRotation &rot);
|
static void rotation(const Transform &t, SHRotation &rot);
|
||||||
|
|
||||||
/** \brief Precomputes normalization coefficients for the first few bands */
|
/// Precomputes normalization coefficients for the first few bands
|
||||||
static void staticInitialization();
|
static void staticInitialization();
|
||||||
|
|
||||||
/// Free the memory taken by staticInitialization()
|
/// Free the memory taken up by staticInitialization()
|
||||||
static void staticShutdown();
|
static void staticShutdown();
|
||||||
protected:
|
protected:
|
||||||
/// Helper function for rotation() -- computes a diagonal block based on the previous level
|
/// Helper function for rotation() -- computes a diagonal block based on the previous level
|
||||||
|
|
|
@ -41,6 +41,7 @@ MTS_NAMESPACE_BEGIN
|
||||||
* Note: SSH streams are set to use network byte order by default.
|
* Note: SSH streams are set to use network byte order by default.
|
||||||
*
|
*
|
||||||
* \ingroup libcore
|
* \ingroup libcore
|
||||||
|
* \ingroup libpython
|
||||||
*/
|
*/
|
||||||
class MTS_EXPORT_CORE SSHStream : public Stream {
|
class MTS_EXPORT_CORE SSHStream : public Stream {
|
||||||
public:
|
public:
|
||||||
|
@ -49,10 +50,11 @@ public:
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new SSH stream. The timeout parameter specifies specifies
|
* \brief Create a new SSH stream.
|
||||||
* the maximum amount of time that can be spent before failing to
|
*
|
||||||
* create the initial connection. This feature is unsupported
|
* The timeout parameter specifies specifies the maximum amount of
|
||||||
* (and ignored) on Windows.
|
* time that can be spent before failing to create the initial
|
||||||
|
* connection. This feature is unsupported (and ignored) on Windows.
|
||||||
*
|
*
|
||||||
* \param userName Username to use for the authentication
|
* \param userName Username to use for the authentication
|
||||||
* \param hostName Destination host name
|
* \param hostName Destination host name
|
||||||
|
|
|
@ -36,6 +36,7 @@ MTS_NAMESPACE_BEGIN
|
||||||
* order (= big endian).
|
* order (= big endian).
|
||||||
*
|
*
|
||||||
* \ingroup libcore
|
* \ingroup libcore
|
||||||
|
* \ingroup libpython
|
||||||
*/
|
*/
|
||||||
class MTS_EXPORT_CORE SocketStream : public Stream {
|
class MTS_EXPORT_CORE SocketStream : public Stream {
|
||||||
public:
|
public:
|
||||||
|
@ -43,7 +44,10 @@ public:
|
||||||
//! @{ \name Constructors
|
//! @{ \name Constructors
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|
||||||
/// Create a stream from an existing socket
|
/**
|
||||||
|
* \brief Create a stream from an existing socket
|
||||||
|
* \remark This function is not exposed in the Python bindings
|
||||||
|
*/
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
SocketStream(SOCKET socket);
|
SocketStream(SOCKET socket);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -257,7 +257,11 @@ private:
|
||||||
/** \brief Collects various rendering statistics and presents them
|
/** \brief Collects various rendering statistics and presents them
|
||||||
* in a human-readable form.
|
* in a human-readable form.
|
||||||
*
|
*
|
||||||
|
* \remark Only the \ref getInstance(), \ref getStats(), and
|
||||||
|
* \ref printStats() functions are implemented in the Python bindings.
|
||||||
|
*
|
||||||
* \ingroup libcore
|
* \ingroup libcore
|
||||||
|
* \ingroup libpython
|
||||||
*/
|
*/
|
||||||
class MTS_EXPORT_CORE Statistics : public Object {
|
class MTS_EXPORT_CORE Statistics : public Object {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -26,30 +26,54 @@
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render job - coordinates the process of rendering a single
|
* \brief Coordinates the process of rendering a single image.
|
||||||
* image. Implemented as a thread so that multiple jobs can
|
*
|
||||||
|
* Implemented as a thread so that multiple jobs can
|
||||||
* be executed concurrently.
|
* be executed concurrently.
|
||||||
|
*
|
||||||
* \ingroup librender
|
* \ingroup librender
|
||||||
|
* \ingroup libpython
|
||||||
*/
|
*/
|
||||||
class MTS_EXPORT_RENDER RenderJob : public Thread {
|
class MTS_EXPORT_RENDER RenderJob : public Thread {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Create a new render job for the given scene. When the
|
* \brief Create a new render job for the given scene.
|
||||||
* scene, sampler or camera are already registered with the scheduler,
|
*
|
||||||
* the last parameters can optionally be specified (that way
|
* When the Resource ID parameters (\c sceneResID, \c cameraResID, ..) are
|
||||||
* they do not have to be re-sent to network rendering servers).
|
* set to \c -1, the implementation will automatically register the
|
||||||
|
* associated objects (scene, camera, sampler) with the scheduler and
|
||||||
|
* forward copies to all involved network rendering workers. When some
|
||||||
|
* of these resources have already been registered with
|
||||||
|
* the scheduler, their IDs can be provided to avoid this extra
|
||||||
|
* communication cost.
|
||||||
|
*
|
||||||
|
* \param threadName
|
||||||
|
* Thread name identifier for this render job
|
||||||
|
* \param scene
|
||||||
|
* Scene to be rendered
|
||||||
|
* \param queue
|
||||||
|
* Pointer to a queue, to which this job should be added
|
||||||
|
* \param sceneResID
|
||||||
|
* Resource ID of \c scene (or \c -1)
|
||||||
|
* \param cameraResID
|
||||||
|
* Resource ID of \c scene->getCamera() (or \c -1)
|
||||||
|
* \param samplerResID
|
||||||
|
* Resource ID of the sample generator (or \c -1)
|
||||||
|
* \param threadIsCritical
|
||||||
|
* When set to \c true, the entire program will terminate
|
||||||
|
* if this thread fails unexpectedly.
|
||||||
|
* \param testSupervisor
|
||||||
|
* When this image is being rendered as part of a test suite,
|
||||||
|
* this parameter points to the associated \ref TestSupervisor
|
||||||
|
* instance.
|
||||||
*/
|
*/
|
||||||
RenderJob(const std::string &threadName,
|
RenderJob(const std::string &threadName,
|
||||||
Scene *scene, RenderQueue *queue,
|
Scene *scene, RenderQueue *queue,
|
||||||
TestSupervisor *testSupervisor,
|
|
||||||
int sceneResID = -1,
|
int sceneResID = -1,
|
||||||
int cameraResID = -1,
|
int cameraResID = -1,
|
||||||
int samplerResID = -1,
|
int samplerResID = -1,
|
||||||
bool threadIsCritical = true,
|
bool threadIsCritical = true,
|
||||||
bool visualFeedback = false);
|
TestSupervisor *testSupervisor = NULL);
|
||||||
|
|
||||||
/// Should visual feedback be provided (true when rendering using the GUI)
|
|
||||||
inline bool hasVisualFeedback() const { return m_visualFeedback; }
|
|
||||||
|
|
||||||
/// Write out the current (partially rendered) image
|
/// Write out the current (partially rendered) image
|
||||||
inline void flush() { m_scene->flush(); }
|
inline void flush() { m_scene->flush(); }
|
||||||
|
@ -74,7 +98,6 @@ private:
|
||||||
bool m_ownsSceneResource;
|
bool m_ownsSceneResource;
|
||||||
bool m_ownsCameraResource;
|
bool m_ownsCameraResource;
|
||||||
bool m_ownsSamplerResource;
|
bool m_ownsSamplerResource;
|
||||||
bool m_visualFeedback;
|
|
||||||
bool m_cancelled;
|
bool m_cancelled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,12 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render queue - used to keep track of a number of scenes
|
* \brief Render queue - used to keep track of a number of scenes
|
||||||
* that are simultaneously being rendered. Also distributes
|
* that are simultaneously being rendered.
|
||||||
* events regarding these scenes to registered listeners.
|
*
|
||||||
|
* This class is also responsible for distributing events about
|
||||||
|
* in-progress renderings to registered listeners.
|
||||||
|
*
|
||||||
* \ingroup librender
|
* \ingroup librender
|
||||||
*/
|
*/
|
||||||
class MTS_EXPORT_RENDER RenderQueue : public Object {
|
class MTS_EXPORT_RENDER RenderQueue : public Object {
|
||||||
|
|
|
@ -39,10 +39,12 @@ MTS_NAMESPACE_BEGIN
|
||||||
/**
|
/**
|
||||||
* \brief Principal scene data structure
|
* \brief Principal scene data structure
|
||||||
*
|
*
|
||||||
* Holds information on surfaces, luminaires and participating media and
|
* This class holds information on surfaces, luminaires and participating media
|
||||||
* coordinates rendering jobs. This class also provides useful query routines
|
* and coordinates rendering jobs. It also provides useful query routines that
|
||||||
* that are mostly used by the \ref Integrator implementations.
|
* are mostly used by the \ref Integrator implementations.
|
||||||
|
*
|
||||||
* \ingroup librender
|
* \ingroup librender
|
||||||
|
* \ingroup libpython
|
||||||
*/
|
*/
|
||||||
class MTS_EXPORT_RENDER Scene : public NetworkedObject {
|
class MTS_EXPORT_RENDER Scene : public NetworkedObject {
|
||||||
public:
|
public:
|
||||||
|
@ -64,6 +66,9 @@ public:
|
||||||
// =============================================================
|
// =============================================================
|
||||||
//! @{ \name Initialization and rendering
|
//! @{ \name Initialization and rendering
|
||||||
// =============================================================
|
// =============================================================
|
||||||
|
|
||||||
|
/// Construct a new, empty scene (with the default properties)
|
||||||
|
Scene();
|
||||||
|
|
||||||
/// Construct a new, empty scene
|
/// Construct a new, empty scene
|
||||||
Scene(const Properties &props);
|
Scene(const Properties &props);
|
||||||
|
@ -85,7 +90,7 @@ public:
|
||||||
* before rendering the scene. This might do a variety of things,
|
* before rendering the scene. This might do a variety of things,
|
||||||
* such as constructing photon maps or executing distributed overture
|
* such as constructing photon maps or executing distributed overture
|
||||||
* passes. Progress is tracked by sending status messages to a provided
|
* passes. Progress is tracked by sending status messages to a provided
|
||||||
* render queue. The parameter <tt>job</tt> is required to discern
|
* render queue. The parameter \c job is required to discern
|
||||||
* multiple render jobs occurring in parallel. The last three parameters
|
* multiple render jobs occurring in parallel. The last three parameters
|
||||||
* are resource IDs of the associated scene, camera and sample generator,
|
* are resource IDs of the associated scene, camera and sample generator,
|
||||||
* which have been made available to all local and remote workers.
|
* which have been made available to all local and remote workers.
|
||||||
|
@ -97,14 +102,14 @@ public:
|
||||||
/**
|
/**
|
||||||
* Render the scene as seen by the scene's main camera. Progress is tracked
|
* Render the scene as seen by the scene's main camera. Progress is tracked
|
||||||
* by sending status messages to a provided render queue. The parameter
|
* by sending status messages to a provided render queue. The parameter
|
||||||
* <tt>job</tt> is required to discern multiple render jobs occurring in
|
* \c job is required to discern multiple render jobs occurring in
|
||||||
* parallel. The last three parameters are resource IDs of the associated
|
* parallel. The last three parameters are resource IDs of the associated
|
||||||
* scene, camera and sample generator, which have been made available to
|
* scene, camera and sample generator, which have been made available to
|
||||||
* all local and remote workers. Returns true upon successful completion.
|
* all local and remote workers. Returns true upon successful completion.
|
||||||
*/
|
*/
|
||||||
bool render(RenderQueue *queue, const RenderJob *job,
|
bool render(RenderQueue *queue, const RenderJob *job,
|
||||||
int sceneResID, int cameraResID, int samplerResID);
|
int sceneResID, int cameraResID, int samplerResID);
|
||||||
|
|
||||||
/// Post-process step after rendering. Parameters are explained above
|
/// Post-process step after rendering. Parameters are explained above
|
||||||
void postprocess(RenderQueue *queue, const RenderJob *job,
|
void postprocess(RenderQueue *queue, const RenderJob *job,
|
||||||
int sceneResID, int cameraResID, int samplerResID);
|
int sceneResID, int cameraResID, int samplerResID);
|
||||||
|
@ -428,12 +433,14 @@ public:
|
||||||
inline Float getTestThreshold() const { return m_testThresh; }
|
inline Float getTestThreshold() const { return m_testThresh; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the scene's camera. Note that the camera is not included
|
* \brief Set the scene's camera.
|
||||||
* when this Scene instance is serialized -- the camera field
|
*
|
||||||
* will be <tt>NULL</tt> after unserialization. This is intentional
|
* Note that the camera is not included when this Scene instance
|
||||||
* so that the camera can be changed without having to re-transmit
|
* is serialized -- the camera field will be \c NULL after
|
||||||
* the whole scene. Hence, the camera needs to be submitted separately
|
* unserialization. This is intentional so that the camera can
|
||||||
* and re-attached on the remote side using <tt>setCamera</tt>.
|
* be changed without having to re-transmit the whole scene.
|
||||||
|
* Hence, the camera needs to be submitted separately
|
||||||
|
* and re-attached on the remote side using \ref setCamera().
|
||||||
**/
|
**/
|
||||||
inline void setCamera(Camera *camera) { m_camera = camera; }
|
inline void setCamera(Camera *camera) { m_camera = camera; }
|
||||||
/// Return the scene's camera
|
/// Return the scene's camera
|
||||||
|
@ -442,12 +449,14 @@ public:
|
||||||
inline const Camera *getCamera() const { return m_camera.get(); }
|
inline const Camera *getCamera() const { return m_camera.get(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the scene's integrator. Note that the integrator is not included
|
* \brief Set the scene's integrator.
|
||||||
* when this Scene instance is serialized -- the integrator field
|
*
|
||||||
* will be <tt>NULL</tt> after unserialization. This is intentional
|
* Note that the integrator is not included when this Scene instance
|
||||||
* so that the integrator can be changed without having to re-transmit
|
* is serialized -- the integrator field will be \c NULL after
|
||||||
* the whole scene. Hence, the integrator needs to be submitted separately
|
* unserialization. This is intentional so that the integrator can
|
||||||
* and re-attached on the remote side using <tt>setIntegrator</tt>.
|
* be changed without having to re-transmit the whole scene. Hence,
|
||||||
|
* the integrator needs to be submitted separately and re-attached
|
||||||
|
* on the remote side using \ref setIntegrator().
|
||||||
**/
|
**/
|
||||||
inline void setIntegrator(Integrator *integrator) { m_integrator = integrator; }
|
inline void setIntegrator(Integrator *integrator) { m_integrator = integrator; }
|
||||||
/// Return the scene's integrator
|
/// Return the scene's integrator
|
||||||
|
@ -456,22 +465,26 @@ public:
|
||||||
inline const Integrator *getIntegrator() const { return m_integrator.get(); }
|
inline const Integrator *getIntegrator() const { return m_integrator.get(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the scene's sampler. Note that the sampler is not included
|
* \brief Set the scene's sampler.
|
||||||
* when this Scene instance is serialized -- the sampler field
|
*
|
||||||
* will be <tt>NULL</tt> after unserialization. This is intentional
|
* Note that the sampler is not included when this Scene instance
|
||||||
* so that the sampler can be changed without having to re-transmit
|
* is serialized -- the sampler field will be \c NULL after
|
||||||
* the whole scene. Hence, the sampler needs to be submitted separately
|
* unserialization. This is intentional so that the sampler can
|
||||||
* and re-attached on the remote side using <tt>setSampler</tt>.
|
* be changed without having to re-transmit the whole scene.
|
||||||
|
* Hence, the sampler needs to be submitted separately
|
||||||
|
* and re-attached on the remote side using \ref setSampler().
|
||||||
**/
|
**/
|
||||||
inline void setSampler(Sampler *sampler) { m_sampler = sampler; }
|
inline void setSampler(Sampler *sampler) { m_sampler = sampler; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the scene's sampler. Note that when rendering using multiple
|
* \brief Return the scene's sampler.
|
||||||
* different threads, each thread will be passed a shallow copy of the
|
*
|
||||||
* scene, which has a different sampler instance. This helps to avoid
|
* Note that when rendering using multiple different threads, each
|
||||||
* locking/contention issues and ensures that different threads render
|
* thread will be passed a shallow copy of the scene, which has a
|
||||||
* with different random number sequences. The sampler instance provided
|
* different sampler instance. This helps to avoid locking/contention
|
||||||
* here is a clone of the original sampler specified in the camera.
|
* issues and ensures that different threads render with different
|
||||||
|
* random number sequences. The sampler instance provided here is a
|
||||||
|
* clone of the original sampler specified in the camera.
|
||||||
*/
|
*/
|
||||||
inline Sampler *getSampler() { return m_sampler; }
|
inline Sampler *getSampler() { return m_sampler; }
|
||||||
/// Return the scene's sampler
|
/// Return the scene's sampler
|
||||||
|
|
|
@ -50,8 +50,12 @@ private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief XML parser for Mitsuba scene files. To be used with the
|
* \brief XML parser for Mitsuba scene files. To be used with the
|
||||||
* SAX interface Xerces-C++.
|
* SAX interface of Xerces-C++.
|
||||||
|
*
|
||||||
|
* \remark In the Python bindings, only the static function
|
||||||
|
* \ref loadScene() is exposed.
|
||||||
* \ingroup librender
|
* \ingroup librender
|
||||||
|
* \ingroup libpython
|
||||||
*/
|
*/
|
||||||
class MTS_EXPORT_RENDER SceneHandler : public HandlerBase {
|
class MTS_EXPORT_RENDER SceneHandler : public HandlerBase {
|
||||||
public:
|
public:
|
||||||
|
@ -62,6 +66,16 @@ public:
|
||||||
NamedObjectMap *objects = NULL, bool isIncludedFile = false);
|
NamedObjectMap *objects = NULL, bool isIncludedFile = false);
|
||||||
virtual ~SceneHandler();
|
virtual ~SceneHandler();
|
||||||
|
|
||||||
|
/// Convenience method -- load a scene from a given filename
|
||||||
|
static ref<Scene> loadScene(const fs::path &filename,
|
||||||
|
const ParameterMap ¶ms= ParameterMap());
|
||||||
|
|
||||||
|
/// Initialize Xerces-C++ (needs to be called once at program startup)
|
||||||
|
static void staticInitialization();
|
||||||
|
|
||||||
|
/// Free the memory taken up by staticInitialization()
|
||||||
|
static void staticShutdown();
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Implementation of the SAX DocumentHandler interface
|
// Implementation of the SAX DocumentHandler interface
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
|
@ -204,7 +204,7 @@ SerializableObject *Scheduler::getResource(int id, int coreIndex) {
|
||||||
m_mutex->unlock();
|
m_mutex->unlock();
|
||||||
Log(EError, "getResource(): tried to look up manifold resource %i without specifying a core index!", id);
|
Log(EError, "getResource(): tried to look up manifold resource %i without specifying a core index!", id);
|
||||||
}
|
}
|
||||||
result = rec->resources[coreIndex];
|
result = rec->resources.at(coreIndex);
|
||||||
} else {
|
} else {
|
||||||
result = rec->resources[0];
|
result = rec->resources[0];
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,4 +13,4 @@ if pythonEnv.has_key('PYTHONLIB'):
|
||||||
pythonEnv.Prepend(LIBS=pythonEnv['PYTHONLIB'])
|
pythonEnv.Prepend(LIBS=pythonEnv['PYTHONLIB'])
|
||||||
|
|
||||||
if hasPython:
|
if hasPython:
|
||||||
libpython = pythonEnv.SharedLibrary('mitsuba', ['core.cpp']);
|
libpython = pythonEnv.SharedLibrary('mitsuba', ['core.cpp', 'render.cpp']);
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(__MTSPY_H)
|
#if !defined(__PYTHON_BASE_H)
|
||||||
#define __MTSPY_H
|
#define __PYTHON_BASE_H
|
||||||
|
|
||||||
#include <mitsuba/mitsuba.h>
|
#include <mitsuba/mitsuba.h>
|
||||||
|
|
||||||
|
@ -151,5 +151,8 @@ typedef std::vector<std::string> StringVector;
|
||||||
typedef std::vector<mitsuba::SerializableObject *> SerializableObjectVector;
|
typedef std::vector<mitsuba::SerializableObject *> SerializableObjectVector;
|
||||||
typedef std::map<std::string, std::string> StringMap;
|
typedef std::map<std::string, std::string> StringMap;
|
||||||
|
|
||||||
#endif /* __MTSPY_H */
|
extern void export_core();
|
||||||
|
extern void export_render();
|
||||||
|
|
||||||
|
#endif /* __PYTHON_BASE_H */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "core.h"
|
#include "base.h"
|
||||||
#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>
|
||||||
|
@ -13,6 +13,10 @@
|
||||||
#include <mitsuba/core/aabb.h>
|
#include <mitsuba/core/aabb.h>
|
||||||
#include <mitsuba/core/frame.h>
|
#include <mitsuba/core/frame.h>
|
||||||
#include <mitsuba/core/sched_remote.h>
|
#include <mitsuba/core/sched_remote.h>
|
||||||
|
#include <mitsuba/core/netobject.h>
|
||||||
|
#include <mitsuba/core/sstream.h>
|
||||||
|
#include <mitsuba/core/sshstream.h>
|
||||||
|
#include <mitsuba/render/scenehandler.h>
|
||||||
|
|
||||||
using namespace mitsuba;
|
using namespace mitsuba;
|
||||||
|
|
||||||
|
@ -26,10 +30,12 @@ void initializeFramework() {
|
||||||
Spectrum::staticInitialization();
|
Spectrum::staticInitialization();
|
||||||
Scheduler::staticInitialization();
|
Scheduler::staticInitialization();
|
||||||
SHVector::staticInitialization();
|
SHVector::staticInitialization();
|
||||||
|
SceneHandler::staticInitialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdownFramework() {
|
void shutdownFramework() {
|
||||||
/* Shutdown the core framework */
|
/* Shutdown the core framework */
|
||||||
|
SceneHandler::staticShutdown();
|
||||||
SHVector::staticShutdown();
|
SHVector::staticShutdown();
|
||||||
Scheduler::staticShutdown();
|
Scheduler::staticShutdown();
|
||||||
Spectrum::staticShutdown();
|
Spectrum::staticShutdown();
|
||||||
|
@ -282,6 +288,40 @@ Point transform_mul_point(Transform *transform, const Point &point) { return tra
|
||||||
Ray transform_mul_ray(Transform *transform, const Ray &ray) { return transform->operator()(ray); }
|
Ray transform_mul_ray(Transform *transform, const Ray &ray) { return transform->operator()(ray); }
|
||||||
Transform transform_mul_transform(Transform *transform, const Transform &other) { return *transform * other; }
|
Transform transform_mul_transform(Transform *transform, const Transform &other) { return *transform * other; }
|
||||||
|
|
||||||
|
ConfigurableObject *pluginmgr_create(PluginManager *manager, bp::dict dict) {
|
||||||
|
Properties properties;
|
||||||
|
bp::list list = dict.items();
|
||||||
|
std::map<std::string, ConfigurableObject *> children;
|
||||||
|
|
||||||
|
for (int i=0; i<bp::len(list); ++i) {
|
||||||
|
bp::tuple tuple = bp::extract<bp::tuple>(list[i]);
|
||||||
|
std::string name = bp::extract<std::string>(tuple[0]);
|
||||||
|
bp::extract<bp::dict> extractDict(tuple[1]);
|
||||||
|
bp::extract<std::string> extractString(tuple[1]);
|
||||||
|
bp::extract<ConfigurableObject *> extractConfigurableObject(tuple[1]);
|
||||||
|
|
||||||
|
if (name == "type") {
|
||||||
|
if (!extractString.check())
|
||||||
|
SLog(EError, "'type' property must map to a string!");
|
||||||
|
else
|
||||||
|
properties.setPluginName(extractString());
|
||||||
|
} else if (extractDict.check()) {
|
||||||
|
children[name] = pluginmgr_create(manager, extractDict());
|
||||||
|
} else if (extractConfigurableObject.check()) {
|
||||||
|
children[name] = extractConfigurableObject();
|
||||||
|
} else {
|
||||||
|
properties_wrapper::set(properties, name, tuple[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurableObject *object = manager->createObject(properties);
|
||||||
|
for (std::map<std::string, ConfigurableObject *>::iterator it = children.begin();
|
||||||
|
it != children.end(); ++it)
|
||||||
|
object->addChild(it->first, it->second);
|
||||||
|
object->configure();
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fromLinearRGB_overloads, fromLinearRGB, 3, 4)
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fromLinearRGB_overloads, fromLinearRGB, 3, 4)
|
||||||
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fromXYZ_overloads, fromXYZ, 3, 4)
|
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fromXYZ_overloads, fromXYZ, 3, 4)
|
||||||
|
|
||||||
|
@ -296,6 +336,12 @@ void export_core() {
|
||||||
|
|
||||||
BP_SETSCOPE(coreModule);
|
BP_SETSCOPE(coreModule);
|
||||||
|
|
||||||
|
/* Basic STL containers */
|
||||||
|
bp::class_<StringVector>("StringVector")
|
||||||
|
.def(bp::vector_indexing_suite<StringVector>());
|
||||||
|
bp::class_<StringMap>("StringMap")
|
||||||
|
.def(bp::map_indexing_suite<StringMap>());
|
||||||
|
|
||||||
bp::enum_<ELogLevel>("ELogLevel")
|
bp::enum_<ELogLevel>("ELogLevel")
|
||||||
.value("ETrace", ETrace)
|
.value("ETrace", ETrace)
|
||||||
.value("EDebug", EDebug)
|
.value("EDebug", EDebug)
|
||||||
|
@ -381,6 +427,19 @@ void export_core() {
|
||||||
.def("close", &FileStream::close)
|
.def("close", &FileStream::close)
|
||||||
.def("remove", &FileStream::remove);
|
.def("remove", &FileStream::remove);
|
||||||
|
|
||||||
|
BP_CLASS(SocketStream, Stream, (bp::init<std::string, int>()))
|
||||||
|
.def("getPeer", &SocketStream::getPeer, BP_RETURN_CONSTREF)
|
||||||
|
.def("getReceivedBytes", &SocketStream::getReceivedBytes)
|
||||||
|
.def("getSentBytes", &SocketStream::getSentBytes);
|
||||||
|
|
||||||
|
BP_CLASS(SSHStream, Stream, (bp::init<std::string, std::string, const StringVector &>()))
|
||||||
|
.def(bp::init<std::string, std::string, const StringVector &, int>())
|
||||||
|
.def(bp::init<std::string, std::string, const StringVector &, int, int>())
|
||||||
|
.def("getUserName", &SSHStream::getUserName, BP_RETURN_CONSTREF)
|
||||||
|
.def("getHostName", &SSHStream::getHostName, BP_RETURN_CONSTREF)
|
||||||
|
.def("getReceivedBytes", &SSHStream::getReceivedBytes)
|
||||||
|
.def("getSentBytes", &SSHStream::getSentBytes);
|
||||||
|
|
||||||
BP_SETSCOPE(FileStream_class);
|
BP_SETSCOPE(FileStream_class);
|
||||||
bp::enum_<FileStream::EFileMode>("EFileMode")
|
bp::enum_<FileStream::EFileMode>("EFileMode")
|
||||||
.value("EReadOnly", FileStream::EReadOnly)
|
.value("EReadOnly", FileStream::EReadOnly)
|
||||||
|
@ -394,7 +453,7 @@ void export_core() {
|
||||||
|
|
||||||
BP_CLASS(SerializableObject, Object, bp::no_init)
|
BP_CLASS(SerializableObject, Object, bp::no_init)
|
||||||
.def("serialize", &SerializableObject::serialize);
|
.def("serialize", &SerializableObject::serialize);
|
||||||
|
|
||||||
ConfigurableObject *(ConfigurableObject::*cobject_get_parent)() = &ConfigurableObject::getParent;
|
ConfigurableObject *(ConfigurableObject::*cobject_get_parent)() = &ConfigurableObject::getParent;
|
||||||
void (ConfigurableObject::*cobject_add_child_1)(ConfigurableObject *) = &ConfigurableObject::addChild;
|
void (ConfigurableObject::*cobject_add_child_1)(ConfigurableObject *) = &ConfigurableObject::addChild;
|
||||||
void (ConfigurableObject::*cobject_add_child_2)(const std::string &, ConfigurableObject *) = &ConfigurableObject::addChild;
|
void (ConfigurableObject::*cobject_add_child_2)(const std::string &, ConfigurableObject *) = &ConfigurableObject::addChild;
|
||||||
|
@ -406,6 +465,9 @@ void export_core() {
|
||||||
.def("addChild", cobject_add_child_2)
|
.def("addChild", cobject_add_child_2)
|
||||||
.def("configure", &ConfigurableObject::configure);
|
.def("configure", &ConfigurableObject::configure);
|
||||||
|
|
||||||
|
BP_CLASS(NetworkedObject, ConfigurableObject, bp::no_init)
|
||||||
|
.def("bindUsedResources", &NetworkedObject::bindUsedResources);
|
||||||
|
|
||||||
Thread *(Thread::*thread_get_parent)() = &Thread::getParent;
|
Thread *(Thread::*thread_get_parent)() = &Thread::getParent;
|
||||||
BP_CLASS(Thread, Object, bp::no_init)
|
BP_CLASS(Thread, Object, bp::no_init)
|
||||||
.def("getID", &Thread::getID)
|
.def("getID", &Thread::getID)
|
||||||
|
@ -538,11 +600,18 @@ void export_core() {
|
||||||
BP_CLASS(PluginManager, Object, bp::no_init)
|
BP_CLASS(PluginManager, Object, bp::no_init)
|
||||||
.def("ensurePluginLoaded", &PluginManager::ensurePluginLoaded)
|
.def("ensurePluginLoaded", &PluginManager::ensurePluginLoaded)
|
||||||
.def("getLoadedPlugins", &PluginManager::getLoadedPlugins)
|
.def("getLoadedPlugins", &PluginManager::getLoadedPlugins)
|
||||||
|
.def("create", pluginmgr_create, BP_RETURN_VALUE)
|
||||||
.def("createObject", pluginmgr_createobject_1, BP_RETURN_VALUE)
|
.def("createObject", pluginmgr_createobject_1, BP_RETURN_VALUE)
|
||||||
.def("createObject", pluginmgr_createobject_2, BP_RETURN_VALUE)
|
.def("createObject", pluginmgr_createobject_2, BP_RETURN_VALUE)
|
||||||
.def("getInstance", &PluginManager::getInstance, BP_RETURN_VALUE)
|
.def("getInstance", &PluginManager::getInstance, BP_RETURN_VALUE)
|
||||||
.staticmethod("getInstance");
|
.staticmethod("getInstance");
|
||||||
|
|
||||||
|
BP_CLASS(Statistics, Object, bp::no_init)
|
||||||
|
.def("getStats", &Statistics::getStats, BP_RETURN_VALUE)
|
||||||
|
.def("printStats", &Statistics::printStats)
|
||||||
|
.def("getInstance", &Statistics::getInstance, BP_RETURN_VALUE)
|
||||||
|
.staticmethod("getInstance");
|
||||||
|
|
||||||
BP_CLASS(WorkUnit, Object, bp::no_init)
|
BP_CLASS(WorkUnit, Object, bp::no_init)
|
||||||
.def("set", &WorkUnit::set)
|
.def("set", &WorkUnit::set)
|
||||||
.def("load", &WorkUnit::load)
|
.def("load", &WorkUnit::load)
|
||||||
|
@ -999,16 +1068,11 @@ BOOST_PYTHON_MODULE(mitsuba) {
|
||||||
bp::object package = bp::scope();
|
bp::object package = bp::scope();
|
||||||
package.attr("__path__") = "mitsuba";
|
package.attr("__path__") = "mitsuba";
|
||||||
|
|
||||||
/* Basic STL containers */
|
|
||||||
bp::class_<StringVector>("StringVector")
|
|
||||||
.def(bp::vector_indexing_suite<StringVector>());
|
|
||||||
bp::class_<StringMap>("StringMap")
|
|
||||||
.def(bp::map_indexing_suite<StringMap>());
|
|
||||||
|
|
||||||
/* Automatically take care of the framework
|
/* Automatically take care of the framework
|
||||||
initialization / shutdown */
|
initialization / shutdown */
|
||||||
initializeFramework();
|
initializeFramework();
|
||||||
atexit(shutdownFramework);
|
atexit(shutdownFramework);
|
||||||
|
|
||||||
export_core();
|
export_core();
|
||||||
|
export_render();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,10 @@
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
RenderJob::RenderJob(const std::string &threadName,
|
RenderJob::RenderJob(const std::string &threadName,
|
||||||
Scene *scene, RenderQueue *queue, TestSupervisor *testSupervisor,
|
Scene *scene, RenderQueue *queue, int sceneResID, int cameraResID,
|
||||||
int sceneResID, int cameraResID, int samplerResID, bool threadIsCritical,
|
int samplerResID, bool threadIsCritical, TestSupervisor *supervisor)
|
||||||
bool visualFeedback) : Thread(threadName), m_scene(scene), m_queue(queue),
|
: Thread(threadName), m_scene(scene), m_queue(queue),
|
||||||
m_testSupervisor(testSupervisor), m_visualFeedback(visualFeedback) {
|
m_testSupervisor(supervisor) {
|
||||||
|
|
||||||
/* Optional: bring the process down when this thread crashes */
|
/* Optional: bring the process down when this thread crashes */
|
||||||
setCritical(threadIsCritical);
|
setCritical(threadIsCritical);
|
||||||
|
|
|
@ -20,10 +20,20 @@
|
||||||
#include <mitsuba/render/renderjob.h>
|
#include <mitsuba/render/renderjob.h>
|
||||||
#include <mitsuba/core/plugin.h>
|
#include <mitsuba/core/plugin.h>
|
||||||
|
|
||||||
|
#define DEFAULT_BLOCKSIZE 32
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
Scene::Scene()
|
||||||
|
: NetworkedObject(Properties()), m_blockSize(DEFAULT_BLOCKSIZE) {
|
||||||
|
m_kdtree = new ShapeKDTree();
|
||||||
|
m_testType = ENone;
|
||||||
|
m_testThresh = 0.0f;
|
||||||
|
m_importanceSampleLuminaires = true;
|
||||||
|
}
|
||||||
|
|
||||||
Scene::Scene(const Properties &props)
|
Scene::Scene(const Properties &props)
|
||||||
: NetworkedObject(props), m_blockSize(32) {
|
: NetworkedObject(props), m_blockSize(DEFAULT_BLOCKSIZE) {
|
||||||
m_kdtree = new ShapeKDTree();
|
m_kdtree = new ShapeKDTree();
|
||||||
/* When test case mode is active (Mitsuba is started with the -t parameter),
|
/* When test case mode is active (Mitsuba is started with the -t parameter),
|
||||||
this specifies the type of test performed. Mitsuba will expect a reference
|
this specifies the type of test performed. Mitsuba will expect a reference
|
||||||
|
@ -44,7 +54,7 @@ Scene::Scene(const Properties &props)
|
||||||
Log(EError, "Unknown test mode \"%s\" specified (must be \"t-test\" or \"relerr\")",
|
Log(EError, "Unknown test mode \"%s\" specified (must be \"t-test\" or \"relerr\")",
|
||||||
testType.c_str());
|
testType.c_str());
|
||||||
/* Error threshold for use with <tt>testType</tt> */
|
/* Error threshold for use with <tt>testType</tt> */
|
||||||
m_testThresh = props.getFloat("testThresh", 0.01);
|
m_testThresh = props.getFloat("testThresh", 0.01f);
|
||||||
/* By default, luminaire sampling chooses a luminaire with a probability
|
/* By default, luminaire sampling chooses a luminaire with a probability
|
||||||
dependent on the emitted power. Setting this parameter to false switches
|
dependent on the emitted power. Setting this parameter to false switches
|
||||||
to uniform sampling. */
|
to uniform sampling. */
|
||||||
|
|
|
@ -556,4 +556,48 @@ void SceneHandler::fatalError(const SAXParseException& e) {
|
||||||
transcode(e.getMessage()).c_str());
|
transcode(e.getMessage()).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
ref<Scene> SceneHandler::loadScene(const fs::path &filename, const ParameterMap ¶ms) {
|
||||||
|
/* Prepare for parsing scene descriptions */
|
||||||
|
FileResolver *resolver = Thread::getThread()->getFileResolver();
|
||||||
|
SAXParser* parser = new SAXParser();
|
||||||
|
fs::path schemaPath = resolver->resolveAbsolute("data/schema/scene.xsd");
|
||||||
|
SLog(EDebug, "Loading scene \"%s\" ..", filename.file_string().c_str());
|
||||||
|
|
||||||
|
/* Check against the 'scene.xsd' XML Schema */
|
||||||
|
parser->setDoSchema(true);
|
||||||
|
parser->setValidationSchemaFullChecking(true);
|
||||||
|
parser->setValidationScheme(SAXParser::Val_Always);
|
||||||
|
parser->setExternalNoNamespaceSchemaLocation(schemaPath.file_string().c_str());
|
||||||
|
parser->setCalculateSrcOfs(true);
|
||||||
|
|
||||||
|
SceneHandler *handler = new SceneHandler(parser, params);
|
||||||
|
parser->setDoNamespaces(true);
|
||||||
|
parser->setDocumentHandler(handler);
|
||||||
|
parser->setErrorHandler(handler);
|
||||||
|
|
||||||
|
parser->parse(filename.file_string().c_str());
|
||||||
|
ref<Scene> scene = handler->getScene();
|
||||||
|
|
||||||
|
delete parser;
|
||||||
|
delete handler;
|
||||||
|
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneHandler::staticInitialization() {
|
||||||
|
/* Initialize Xerces-C */
|
||||||
|
try {
|
||||||
|
XMLPlatformUtils::Initialize();
|
||||||
|
} catch(const XMLException &toCatch) {
|
||||||
|
SLog(EError, "Error during Xerces initialization: %s",
|
||||||
|
XMLString::transcode(toCatch.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneHandler::staticShutdown() {
|
||||||
|
XMLPlatformUtils::Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
MTS_NAMESPACE_END
|
MTS_NAMESPACE_END
|
||||||
|
|
|
@ -26,31 +26,7 @@ MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
ref<Scene> Utility::loadScene(const std::string &filename,
|
ref<Scene> Utility::loadScene(const std::string &filename,
|
||||||
const ParameterMap ¶ms) {
|
const ParameterMap ¶ms) {
|
||||||
/* Prepare for parsing scene descriptions */
|
return SceneHandler::loadScene(filename, params);
|
||||||
FileResolver *resolver = Thread::getThread()->getFileResolver();
|
|
||||||
SAXParser* parser = new SAXParser();
|
|
||||||
fs::path schemaPath = resolver->resolveAbsolute("data/schema/scene.xsd");
|
|
||||||
Log(EDebug, "Loading scene \"%s\" ..", filename.c_str());
|
|
||||||
|
|
||||||
/* Check against the 'scene.xsd' XML Schema */
|
|
||||||
parser->setDoSchema(true);
|
|
||||||
parser->setValidationSchemaFullChecking(true);
|
|
||||||
parser->setValidationScheme(SAXParser::Val_Always);
|
|
||||||
parser->setExternalNoNamespaceSchemaLocation(schemaPath.file_string().c_str());
|
|
||||||
parser->setCalculateSrcOfs(true);
|
|
||||||
|
|
||||||
SceneHandler *handler = new SceneHandler(parser, params);
|
|
||||||
parser->setDoNamespaces(true);
|
|
||||||
parser->setDocumentHandler(handler);
|
|
||||||
parser->setErrorHandler(handler);
|
|
||||||
|
|
||||||
parser->parse(filename.c_str());
|
|
||||||
ref<Scene> scene = handler->getScene();
|
|
||||||
|
|
||||||
delete parser;
|
|
||||||
delete handler;
|
|
||||||
|
|
||||||
return scene;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MTS_IMPLEMENT_CLASS(Utility, true, Object)
|
MTS_IMPLEMENT_CLASS(Utility, true, Object)
|
||||||
|
|
|
@ -27,6 +27,12 @@ class PointLuminaire : public Luminaire {
|
||||||
public:
|
public:
|
||||||
PointLuminaire(const Properties &props) : Luminaire(props) {
|
PointLuminaire(const Properties &props) : Luminaire(props) {
|
||||||
m_intensity = props.getSpectrum("intensity", Spectrum(1));
|
m_intensity = props.getSpectrum("intensity", Spectrum(1));
|
||||||
|
if (props.hasProperty("position")) {
|
||||||
|
if (props.hasProperty("toWorld"))
|
||||||
|
Log(EError, "Please specify either 'toWorld' or 'position'");
|
||||||
|
m_luminaireToWorld = Transform::translate(Vector(props.getPoint("position")));
|
||||||
|
m_worldToLuminaire = m_luminaireToWorld.inverse();
|
||||||
|
}
|
||||||
m_position = m_luminaireToWorld(Point(0,0,0));
|
m_position = m_luminaireToWorld(Point(0,0,0));
|
||||||
m_type = EDeltaPosition | EDiffuseDirection;
|
m_type = EDeltaPosition | EDiffuseDirection;
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,8 +362,7 @@ int mts_main(int argc, char **argv) {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ref<RenderJob> thr = new RenderJob(formatString("ren%i", jobIdx++),
|
ref<RenderJob> thr = new RenderJob(formatString("ren%i", jobIdx++),
|
||||||
scene, renderQueue, testSupervisor, -1, -1, -1, true,
|
scene, renderQueue, -1, -1, -1, true, testSupervisor);
|
||||||
flushTimer > 0);
|
|
||||||
thr->start();
|
thr->start();
|
||||||
|
|
||||||
renderQueue->waitLeft(numParallelScenes-1);
|
renderQueue->waitLeft(numParallelScenes-1);
|
||||||
|
@ -403,6 +402,7 @@ int main(int argc, char **argv) {
|
||||||
Spectrum::staticInitialization();
|
Spectrum::staticInitialization();
|
||||||
Scheduler::staticInitialization();
|
Scheduler::staticInitialization();
|
||||||
SHVector::staticInitialization();
|
SHVector::staticInitialization();
|
||||||
|
SceneHandler::staticInitialization();
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/* Initialize WINSOCK2 */
|
/* Initialize WINSOCK2 */
|
||||||
|
@ -418,20 +418,10 @@ int main(int argc, char **argv) {
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize Xerces-C */
|
|
||||||
try {
|
|
||||||
XMLPlatformUtils::Initialize();
|
|
||||||
} catch(const XMLException &toCatch) {
|
|
||||||
SLog(EError, "Error during Xerces initialization: %s",
|
|
||||||
XMLString::transcode(toCatch.getMessage()));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int retval = mts_main(argc, argv);
|
int retval = mts_main(argc, argv);
|
||||||
|
|
||||||
XMLPlatformUtils::Terminate();
|
|
||||||
|
|
||||||
/* Shutdown the core framework */
|
/* Shutdown the core framework */
|
||||||
|
SceneHandler::staticShutdown();
|
||||||
SHVector::staticShutdown();
|
SHVector::staticShutdown();
|
||||||
Scheduler::staticShutdown();
|
Scheduler::staticShutdown();
|
||||||
Spectrum::staticShutdown();
|
Spectrum::staticShutdown();
|
||||||
|
|
|
@ -373,6 +373,7 @@ int mts_main(int argc, char **argv) {
|
||||||
Spectrum::staticInitialization();
|
Spectrum::staticInitialization();
|
||||||
Scheduler::staticInitialization();
|
Scheduler::staticInitialization();
|
||||||
SHVector::staticInitialization();
|
SHVector::staticInitialization();
|
||||||
|
SceneHandler::staticInitialization();
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/* Initialize WINSOCK2 */
|
/* Initialize WINSOCK2 */
|
||||||
|
@ -388,20 +389,10 @@ int mts_main(int argc, char **argv) {
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize Xerces-C */
|
|
||||||
try {
|
|
||||||
XMLPlatformUtils::Initialize();
|
|
||||||
} catch(const XMLException &toCatch) {
|
|
||||||
SLog(EError, "Error during Xerces initialization: %s",
|
|
||||||
XMLString::transcode(toCatch.getMessage()));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int retval = mtsutil(argc, argv);
|
int retval = mtsutil(argc, argv);
|
||||||
|
|
||||||
XMLPlatformUtils::Terminate();
|
|
||||||
|
|
||||||
/* Shutdown the core framework */
|
/* Shutdown the core framework */
|
||||||
|
SceneHandler::staticShutdown();
|
||||||
SHVector::staticShutdown();
|
SHVector::staticShutdown();
|
||||||
Scheduler::staticShutdown();
|
Scheduler::staticShutdown();
|
||||||
Spectrum::staticShutdown();
|
Spectrum::staticShutdown();
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xercesc/parsers/SAXParser.hpp>
|
|
||||||
#include <QtGui/QtGui>
|
#include <QtGui/QtGui>
|
||||||
#include <mitsuba/core/shvector.h>
|
#include <mitsuba/core/shvector.h>
|
||||||
#include <mitsuba/core/sched.h>
|
#include <mitsuba/core/sched.h>
|
||||||
|
@ -24,6 +23,7 @@
|
||||||
#include <mitsuba/core/fresolver.h>
|
#include <mitsuba/core/fresolver.h>
|
||||||
#include <mitsuba/core/appender.h>
|
#include <mitsuba/core/appender.h>
|
||||||
#include <mitsuba/core/statistics.h>
|
#include <mitsuba/core/statistics.h>
|
||||||
|
#include <mitsuba/render/scenehandler.h>
|
||||||
#if defined(__OSX__)
|
#if defined(__OSX__)
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -88,15 +88,6 @@ void collect_zombies(int s) {
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* Initialize Xerces-C */
|
|
||||||
try {
|
|
||||||
XMLPlatformUtils::Initialize();
|
|
||||||
} catch(const XMLException &toCatch) {
|
|
||||||
fprintf(stderr, "Error during Xerces initialization: %s",
|
|
||||||
XMLString::transcode(toCatch.getMessage()));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the core framework */
|
/* Initialize the core framework */
|
||||||
Class::staticInitialization();
|
Class::staticInitialization();
|
||||||
PluginManager::staticInitialization();
|
PluginManager::staticInitialization();
|
||||||
|
@ -107,6 +98,7 @@ int main(int argc, char *argv[]) {
|
||||||
Spectrum::staticInitialization();
|
Spectrum::staticInitialization();
|
||||||
Scheduler::staticInitialization();
|
Scheduler::staticInitialization();
|
||||||
SHVector::staticInitialization();
|
SHVector::staticInitialization();
|
||||||
|
SceneHandler::staticInitialization();
|
||||||
|
|
||||||
#if defined(__LINUX__)
|
#if defined(__LINUX__)
|
||||||
XInitThreads();
|
XInitThreads();
|
||||||
|
@ -191,7 +183,6 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
Statistics::getInstance()->printStats();
|
Statistics::getInstance()->printStats();
|
||||||
|
|
||||||
XMLPlatformUtils::Terminate();
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/* Shut down WINSOCK2 */
|
/* Shut down WINSOCK2 */
|
||||||
|
@ -199,6 +190,7 @@ int main(int argc, char *argv[]) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Shutdown the core framework */
|
/* Shutdown the core framework */
|
||||||
|
SceneHandler::staticShutdown();
|
||||||
SHVector::staticShutdown();
|
SHVector::staticShutdown();
|
||||||
Scheduler::staticShutdown();
|
Scheduler::staticShutdown();
|
||||||
Spectrum::staticShutdown();
|
Spectrum::staticShutdown();
|
||||||
|
|
|
@ -1242,8 +1242,8 @@ void MainWindow::on_actionRender_triggered() {
|
||||||
|
|
||||||
Scene *scene = context->scene;
|
Scene *scene = context->scene;
|
||||||
scene->setBlockSize(m_blockSize);
|
scene->setBlockSize(m_blockSize);
|
||||||
context->renderJob = new RenderJob("rend", scene, m_renderQueue, NULL,
|
context->renderJob = new RenderJob("rend", scene, m_renderQueue,
|
||||||
context->sceneResID, -1, -1, false, true);
|
context->sceneResID, -1, -1, false);
|
||||||
context->cancelMode = ERender;
|
context->cancelMode = ERender;
|
||||||
if (context->mode != ERender)
|
if (context->mode != ERender)
|
||||||
ui->glView->downloadFramebuffer();
|
ui->glView->downloadFramebuffer();
|
||||||
|
|
Loading…
Reference in New Issue