git clone https://github.com/mitsuba-renderer/mitsuba.git --branch scons-python3
pip install SCons
这是整个编译过程中最麻烦, 花费时间最多的部分. Mitsuba官方提供了编译好的依赖, 但就是因为他们是编译好的, 有些依赖在VS2019下链接不上. 所以需要自行把Mitsuba的依赖进行更新.
cl.exe
, lib.exe
等等可能会找不到命令我写了一个CMake的脚本, 将Mitsuba用到的依赖都更新到了当前最新(?)的版本, 脚本可在Github上自取. 依赖编译的时间会比较长, 需要耐心等待.
在使用之前, 需要做部分说明
CMakeLists.txt
中有部分内容需要自行修改:
set(COMPILE_THREAD 20)
这里设置的是编译依赖时并行的线程数, 20表示使用20个线程, 设置为本机CPU核数即可.dependencies/Downloads
中. 完成下载后再接着下面的步骤运行具体使用的步骤是这样的:
dependencies
文件夹, 然后将CMakeLists.txt
复制进去dependencies
目录cmake ./
经过漫长的编译后, 依赖就配置完成了. 如果你不确定有没有完成, 那没有关系, 也可以直接跳到"Mitsuba编译"部分. 发生依赖错误的时候在回来, 然后将CMakeLists.txt
中其他的依赖配置代码注释掉, 只留下没有配置成功的依赖, 然后再次运行cmake ./
.
CMakeLists.txt
中包含的依赖列表, 如果你的网络是在太差, 或者不知道怎么让CMake通过代理下载/克隆依赖, 可以参考下面的列表, 手动将需要下载的内容下载好.dependencies/Downloads
下即可依赖 | 路径/文件名 | 克隆命令/下载地址 |
---|---|---|
zlib | zlib/ |
git clone --recurse-submodules https://github.com/madler/zlib.git |
OpenEXR | openexr/ |
git clone --recurse-submodules https://github.com/AcademySoftwareFoundation/openexr.git |
libjpeg-turbo | libjpeg/ |
git clone --recurse-submodules https://github.com/libjpeg-turbo/libjpeg-turbo.git |
libpng | libpng/ |
git clone --recurse-submodules https://github.com/glennrp/libpng.git |
boost | boost/ |
git clone --recurse-submodules --depth=1 --branch=boost-1.77.0 https://github.com/boostorg/boost.git |
xerces-c | xerces-c/ |
git clone --recurse-submodules https://github.com/apache/xerces-c.git |
glew | glew-2.2.0-win32.zip |
https://github.com/nigels-com/glew/releases/download/glew-2.2.0/glew-2.2.0-win32.zip |
half | half-2.2.0.zip |
https://iweb.dl.sourceforge.net/project/half/half/2.2.0/half-2.2.0.zip |
glext | glext.h |
https://www.khronos.org/registry/OpenGL/api/GL/glext.h |
khr | khrplatform.h |
https://www.khronos.org/registry/EGL/api/KHR/khrplatform.h |
FFTW | fftw-3.3.5-dll64.zip |
https://fftw.org/pub/fftw/fftw-3.3.5-dll64.zip |
dependencies/include
: 包含*.h, *.hpp
等头文件dependencies/lib
: 包含*.lib
等库文件dependencies/bin
: 包含*.dll, *.bin
等可执行文件CMakeLists.txt
. Mitsuba中包括了很多个不同的插件, 所以最后整个工程中项目非常多. 目前个人的Github上已经完成了CMake的编译~具体步骤是这样的:
cbuild
, 注意不是在build
下编译(因为那里已经有多个SCons编译相关的文件, 直接编译在那里会把很多文件混在一起).cbuild
, 然后运行cmake ..
config.py
config.py
作为配置, Mitsuba官方在build/
下提供了几个模板, 我们基于这些模板来做修改: 复制build/config-win64-msvc2017.py
到config.py
BASELIB
: BASELIB
中的Half
现在仅包含头文件, 所以可以去掉Half
OEXRINCLUDE
: OpenEXR现在将依赖目录分为了两个, 需要都添加进去OEXRINCLUDE = ['#dependencies/include/OpenEXR', '#dependencies/include/Imath']
OEXRLIB
: OpenEXR的库已经更名, 现在应当为: OEXRLIB = ['OpenEXR-3_1', 'IlmThread-3_1', 'Iex-3_1', 'zlib']
BOOSTINCLUDE
: 源文件中没有这一项, 但是我们的boost includ目录有些不一样, 所以需要加上: BOOSTINCLUDE = ['#dependencies/include/boost-1_77']
BOOSTLIB
: boost system现在不会被编译为库了, 所以需要移除. 另外boost是我们自行编译的, 版本号需要更新: BOOSTLIB = ['libboost_filesystem-vc142-mt-x64-1_77', 'libboost_thread-vc142-mt-x64-1_77']
XERCESLIB = ['xerces-c_4']
我们用的是版本4GLLIB
: 将其中的glew32mx
修改为glew32
PYTHON39LIB
: 这里需要填入两项内容, 第一是boost的python库, 第二是python提供的库: PYTHON39LIB = ['boost_python39-vc142-mt-x64-1_77', 'C:/Program Files/Python39/libs/python39']
PYTHON39INCLUDE
: 填入python提供的头文件目录: PYTHON39INCLUDE = ['C:/Program Files/Python39/include']
QTINCLUDE = ['C:/Qt/5.15.2/msvc2019_64/include']
QTDIR = 'C:/Qt/5.15.2/msvc2019_64'
SConstruct
中可能会用到has_key
, 这是当前不支持的语法, 所以会发生报错:AttributeError: 'SConsEnvironment' object has no attribute 'has_key':
File "H:\mitsuba\SConstruct", line 34:
build('src/libcore/SConscript')
File "H:\mitsuba\SConstruct", line 28:
return SConscript(scriptFile, exports,
File "c:\users\****************************************************\SConscript.py", line 660:
return method(*args, **kw)
File "c:\users\****************************************************\SConscript.py", line 597:
return _SConscript(self.fs, *files, **subst_kw)
File "c:\users\****************************************************\SConscript.py", line 285:
exec(compile(scriptdata, scriptname, 'exec'), call_stack[-1].globals)
File "H:\mitsuba\src\libcore\SConscript", line 5:
if coreEnv.has_key('OEXRLIBDIR'):
has_key
替换为in
即可, 例如: coreEnv.has_key('OEXRLIBDIR')
替换为'OEXRLIBDIR' in coreEnv
SConstruct
文件, 这些文件都需要修改build/SConscript.configure
python_versions = ["2.6", "2.7", "3.0", "3.1", "3.2", "3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9"] # 添加 "3.8", "3.9"
# Line 96
env = Environment(options=vars, ENV = os.environ, tools=['default', 'qt5'], toolpath=['#data/scons'])
print('Checking for Qt 5.x... yes')
hasQt = True
# try:
# env = Environment(options=vars, ENV = os.environ, tools=['default', 'qt5'], toolpath=['#data/scons'])
# print('Checking for Qt 5.x... yes')
# hasQt = True
# except Exception:
# env = Environment(options=vars, ENV = os.environ, tools=['default'], toolpath=['#data/scons'])
# print('Unable to detect a Qt installation -- not building the GUI!')
# hasQt = False
'openexr.h'
代替if not conf.CheckCXXHeader('openexr.h'): # conf.CheckCXXHeader('ImfRgba.h'):
print('OpenEXR is missing (install libopenexr-dev for OpenEXR I/O support)')
else:
env.Append(CPPDEFINES = [['MTS_HAS_OPENEXR', 1]] )
data/scons/qt5.py
SCons.Warnings.Warning
会抛出异常, 所以需要这样修改:# Line 47
# class ToolQtWarning(SCons.Warnings.Warning):
class ToolQtWarning():
pass
class GeneratedMocFileNotIncluded(ToolQtWarning):
pass
class QtdirNotFound(ToolQtWarning):
pass
# SCons.Warnings.enableWarningClass(ToolQtWarning)
build/SConscript.install
if sys.platform == 'win32':
for plugin in plugins:
if '.dll' in plugin.__str__():
installTargets += env.Install(os.path.join(distDir, 'plugins'), plugin)
boost_version = '1_77'
compilerType = 'vc142' # 'vc141'
archType = 'x64' if 'WIN64' in env['CXXFLAGS'] else 'i386'
dllprefix = '#dependencies/bin' # '#dependencies/lib'
if hasCollada:
install(distDir, ['converter/mtsimport.exe'])
sdkDir = os.path.join(distDir, "sdk")
sdkLibDir = os.path.join(sdkDir, "lib")
install(distDir, ['mitsuba/mitsuba.exe', 'mitsuba/mtssrv.exe', 'mitsuba/mtsutil.exe'])
install(distDir, ['libcore/libmitsuba-core.dll', 'libhw/libmitsuba-hw.dll',
'librender/libmitsuba-render.dll', 'libbidir/libmitsuba-bidir.dll'])
install(sdkLibDir, ['libcore/mitsuba-core.lib', 'libhw/mitsuba-hw.lib',
'librender/mitsuba-render.lib', 'libbidir/mitsuba-bidir.lib'])
for entry in os.walk(os.path.join(basePath, "include")):
includeDir = entry[0][len(basePath)+1:]
installTargets += env.Install(os.path.join(sdkDir, includeDir),
[ ('#' + os.path.join(includeDir, fname)) for fname in entry[2] ])
for ver in hasPython:
installAs(os.path.join(distDir, 'python/'+ver+'/mitsuba.pyd'), 'libpython/mitsuba_python' + ver + '.dll')
install(distDir, ['Iex-3_1.dll','IlmThread-3_1.dll', 'Imath-3_2.dll','OpenEXR-3_1.dll','zlib.dll',
'libpng16.dll', 'jpeg62.dll', 'xerces-c_4_0.dll', 'glew32.dll', 'libfftw3-3.dll'],
prefix=dllprefix)
# install(distDir, ['Iex.dll', 'Half.dll','IlmThread.dll', 'Imath.dll','IlmImf.dll','zlib1.dll',
# 'libpng16.dll', 'jpeg.dll', 'xerces-c_3_1.dll', 'glew32mx.dll', 'libfftw3-3.dll'],
# prefix=dllprefix)
for boostlib in ['python39', 'filesystem', 'chrono', 'thread']: # for boostlib in ['python27', 'python35', 'python36', 'system', 'filesystem', 'chrono', 'thread']:
if 'WIN64' in env['CXXFLAGS']:
install(distDir, ['boost_%s-%s-mt-x64-%s.dll' % (boostlib, compilerType, boost_version)], dllprefix)
else:
install(distDir, ['boost_%s-%s-mt-%s.dll' % (boostlib, compilerType, boost_version)], dllprefix) # install(distDir, ['boost_%s-%s-mt-1_64.dll' % (boostlib, compilerType)], dllprefix)
installTargets += env.Install(distDir, '#data/windows/README.txt')
if hasQt:
install(distDir, ['mtsgui/mtsgui.exe'])
install(distDir, ['Qt5Core.dll', 'Qt5Gui.dll', 'Qt5Widgets.dll', 'Qt5Xml.dll',
'Qt5Network.dll', 'Qt5OpenGL.dll', 'Qt5XmlPatterns.dll'], prefix = env['QT5_BINPATH'])# env['QT5_LIBPATH'])
QT5_PLUGIN_PATH = os.path.join(os.path.join('$QTDIR', 'plugins'), 'platforms')
DIST_PLUGIN_PATH = os.path.join(os.path.join(distDir, 'plugins'), 'platforms')
install(DIST_PLUGIN_PATH, ['qdirect2d.dll', 'qdirect2dd.dll',
'qminimal.dll', 'qminimald.dll', 'qoffscreen.dll', 'qoffscreend.dll',
'qwindows.dll', 'qwindowsd.dll'], prefix=QT5_PLUGIN_PATH)
dependencies/version
dependencies/version
这个文件dependencies
文件夹下新建一个文本文件, 取名verison
, 写入内容0.6.0
scons
即可src\libcore\bitmap.cpp(100): error C2039: 'Int64': is not a member of 'Imf'
cl /Fobuild\release\libcore\bitmap.obj /c src\libcore\bitmap.cpp /nologo /Oi /Ot /Oy /Ob1 /Gs /GF /Gy /fp:fast /D WIN32 /D WIN64 /W3 /EHsc /GS- /GL /MD /D MTS_DEBUG /D SINGLE_PRECISION /D SPECTRUM_SAMPLES=3 /D MTS_SSE /D MTS_HAS_COHERENT_RT /D _CONSOLE /D NDEBUG /D OPENEXR_DLL /openmp /nologo /DMTS_BUILD_MODULE=MTS_MODULE_CORE /DMTS_HAS_LIBPNG=1 /DMTS_HAS_LIBJPEG=1 /DMTS_HAS_OPENEXR=1 /DMTS_HAS_FFTW=1 /Idependencies\include\OpenEXR /Idependencies\include\Imath /Idependencies\include\OpenEXR /Idependencies\include\Imath /Idependencies\include\boost-1_77 /Iinclude /Idependencies\include
bitmap.cpp
src\libcore\bitmap.cpp(100): error C2039: 'Int64': is not a member of 'Imf'
src\libcore\bitmap.cpp(100): error C3646: 'tellg': unknown override specifier
src\libcore\bitmap.cpp(100): error C2059: syntax error: '('
src\libcore\bitmap.cpp(100): error C2334: unexpected token(s) preceding '{'; skipping apparent function body
src\libcore\bitmap.cpp(104): error C2039: 'Int64': is not a member of 'Imf'
src\libcore\bitmap.cpp(104): error C2061: syntax error: identifier 'Int64'
src\libcore\bitmap.cpp(105): error C2065: 'pos': undeclared identifier
src\libcore\bitmap.cpp(124): error C2039: 'Int64': is not a member of 'Imf'
src\libcore\bitmap.cpp(124): error C3646: 'tellp': unknown override specifier
src\libcore\bitmap.cpp(124): error C2059: syntax error: '('
src\libcore\bitmap.cpp(124): error C2334: unexpected token(s) preceding '{'; skipping apparent function body
src\libcore\bitmap.cpp(128): error C2039: 'Int64': is not a member of 'Imf'
src\libcore\bitmap.cpp(128): error C2061: syntax error: identifier 'Int64'
src\libcore\bitmap.cpp(129): error C2065: 'pos': undeclared identifier
src\libcore\bitmap.cpp(2781): error C2259: 'mitsuba::EXRIStream': cannot instantiate abstract class
src\libcore\bitmap.cpp(2781): error C2259: 'mitsuba::EXRIStream': cannot instantiate abstract class
Imf::Int64
被替换为C++自带的64位整数int64_t
或者uint64_t
, 这里需要将报错的地方进行相应的替换. 另外, 替换的时候注意要根据父类的函数返回值和参数类型来替换uint64_t tellg() { // Imf::Int64 tellg() { // Line 100
void seekg(uint64_t pos) { // void seekg(Imf::Int64 pos) { // Line 104
uint64_t tellp() { // Imf::Int64 tellp() { // Line 124
void seekp(uint64_t pos) { // void seekp(Imf::Int64 pos) { // Line 128
src\libcore\bitmap.cpp(3013): error C2079: 'frameBuffer' uses undefined class 'Imf_3_1::FrameBuffer'
src\libcore\bitmap.cpp(3013): error C2079: 'frameBuffer' uses undefined class 'Imf_3_1::FrameBuffer'
src\libcore\bitmap.cpp(3025): error C2039: 'Slice': is not a member of 'Imf'
src\libcore\bitmap.cpp(3025): error C3861: 'Slice': identifier not found
src\libcore\bitmap.cpp(3033): error C2039: 'Slice': is not a member of 'Imf'
src\libcore\bitmap.cpp(3033): error C3861: 'Slice': identifier not found
src\libcore\bitmap.cpp(3042): error C2664: 'void Imf_3_1::InputFile::setFrameBuffer(const Imf_3_1::FrameBuffer &)': cannot convert argument 1 from 'int' to 'const Imf_3_1::FrameBuffer &'
src\libcore\bitmap.cpp(3298): error C2079: 'frameBuffer' uses undefined class 'Imf_3_1::FrameBuffer'
src\libcore\bitmap.cpp(3302): error C2039: 'Slice': is not a member of 'Imf'
src\libcore\bitmap.cpp(3302): error C3861: 'Slice': identifier not found
src\libcore\bitmap.cpp(3306): error C2039: 'Slice': is not a member of 'Imf'
src\libcore\bitmap.cpp(3306): error C3861: 'Slice': identifier not found
src\libcore\bitmap.cpp(3308): error C2039: 'Slice': is not a member of 'Imf'
src\libcore\bitmap.cpp(3308): error C3861: 'Slice': identifier not found
src\libcore\bitmap.cpp(3309): error C2039: 'Slice': is not a member of 'Imf'
src\libcore\bitmap.cpp(3309): error C3861: 'Slice': identifier not found
src\libcore\bitmap.cpp(3310): error C2039: 'Slice': is not a member of 'Imf'
src\libcore\bitmap.cpp(3310): error C3861: 'Slice': identifier not found
src\libcore\bitmap.cpp(3315): error C2039: 'Slice': is not a member of 'Imf'
src\libcore\bitmap.cpp(3315): error C3861: 'Slice': identifier not found
src\libcore\bitmap.cpp(3319): error C2039: 'Slice': is not a member of 'Imf'
src\libcore\bitmap.cpp(3319): error C3861: 'Slice': identifier not found
src\libcore\bitmap.cpp(3326): error C2039: 'Slice': is not a member of 'Imf'
src\libcore\bitmap.cpp(3326): error C3861: 'Slice': identifier not found
src\libcore\bitmap.cpp(3330): error C2664: 'void Imf_3_1::OutputFile::setFrameBuffer(const Imf_3_1::FrameBuffer &)': cannot convert argument 1 from 'int' to 'const Imf_3_1::FrameBuffer &'
include/mitsuba/core/half.h
中, #include
后面加上#include
即可build\release\libcore\libmitsuba-core.dll : fatal error LNK1120: 1 unresolved externals imath_half_to_float_table
include/mitsuba/core/half.h
中, #include
前面加一个宏#define IMATH_HALF_NO_LOOKUP_TABLE
就可以了cl /Fobuild\release\libcore\thread.obj /c src\libcore\thread.cpp /nologo /Oi /Ot /Oy /Ob1 /Gs /GF /Gy /fp:fast /D WIN32 /D WIN64 /W3 /EHsc /GS- /GL /MD /D MTS_DEBUG /D SINGLE_PRECISION /D SPECTRUM_SAMPLES=3 /D MTS_SSE /D MTS_HAS_COHERENT_RT /D _CONSOLE /D NDEBUG /D OPENEXR_DLL /openmp /nologo /DMTS_BUILD_MODULE=MTS_MODULE_CORE /DMTS_HAS_LIBPNG=1 /DMTS_HAS_LIBJPEG=1 /Idependencies\include\openexr /Idependencies\include\openexr /Idependencies\include\boost-1_77 /Iinclude /Idependencies\include
thread.cpp
dependencies\include\boost-1_77\boost/system/detail/snprintf.hpp(57): error C2039: '_vsnprintf': is not a member of 'std'
platform.h
将vsnprintf
进行了宏替换, 新版本的boost/MSVC已经不需要这样做了, 这里将用宏定义#if (defined(_MSC_VER) && _MSC_VER < 1900)
把替换的内容注释掉.// include/mitsuba/core/platform.h, Line 215
#if (defined(_MSC_VER) && _MSC_VER < 1900)
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#endif
SAXParser
相关语法错误 util.cpp
include\mitsuba/render/scenehandler.h(33): error C2144: syntax error: 'SAXParser' should be preceded by ';'
include\mitsuba/render/scenehandler.h(33): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
include\mitsuba/render/scenehandler.h(37): error C2143: syntax error: missing ';' before 'namespace'
include\mitsuba/render/scenehandler.h(37): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
include\mitsuba/render/scenehandler.h(170): error C2039: 'XMLTranscoder': is not a member of 'xercesc_4_0'
#define XERCES_CPP_NAMESPACE_BEGIN namespace XERCES_CPP_NAMESPACE {
#define XERCES_CPP_NAMESPACE_END }
#define XERCES_CPP_NAMESPACE_USE using namespace XERCES_CPP_NAMESPACE;
#define XERCES_CPP_NAMESPACE_QUALIFIER XERCES_CPP_NAMESPACE::
src\librender\scenehandler.cpp(667): error C2664: 'void xercesc_4_0::SAXParser::setExternalNoNamespaceSchemaLocation(const XMLCh *const )': cannot convert argument 1 from 'const boost::filesystem::path::value_type *' to 'const XMLCh *const '
filesystem
中的路径转字符串指针时, 需要首先转为string
, 在转为字符串指针. 即将代码中 fs::path::c_str()
替换为 fs::path::string()::c_str()
. 这里会涉及多个文件, 需要在编译的时候再检查替换include\mitsuba/core/tls.h(145): warning C4150: deletion of pointer to incomplete type 'GLEWContextStruct'; no destructor called
glrenderer.cpp
include\mitsuba/core/tls.h(145): warning C4150: deletion of pointer to incomplete type 'GLEWContextStruct'; no destructor called
include\mitsuba/hw/glrenderer.h(25): note: see declaration of 'GLEWContextStruct'
include\mitsuba/core/tls.h(143): note: while compiling class template member function 'void mitsuba::PrimitiveThreadLocal::destruct(void *)'
include\mitsuba/core/tls.h(118): note: see reference to function template instantiation 'void mitsuba::PrimitiveThreadLocal::destruct(void *)' being compiled
src\libhw\glrenderer.cpp(33): note: see reference to class template instantiation 'mitsuba::PrimitiveThreadLocal' being compiled
include\mitsuba/core/tls.h(140): error C2027: use of undefined type 'GLEWContextStruct'
include\mitsuba/hw/glrenderer.h(25): note: see declaration of 'GLEWContextStruct'
include\mitsuba/core/tls.h(139): note: while compiling class template member function 'void *mitsuba::PrimitiveThreadLocal::construct(void)'
include\mitsuba/core/tls.h(118): note: see reference to function template instantiation 'void *mitsuba::PrimitiveThreadLocal::construct(void)' being compiled
scons: *** [build\release\libhw\glrenderer.obj] Error 2
scons: building terminated because of errors.
GLEWContextStruct
这一结构体了, 直接注释GLEWContextStruct
相关的代码即可._1
相关问题 volcache.cpp
src\volume\volcache.cpp(180): error C2065: '_1': undeclared identifier
src\volume\volcache.cpp(181): error C2065: '_1': undeclared identifier
src\volume\volcache.cpp(179): error C2664: 'mitsuba::LRUCache::LRUCache(const mitsuba::LRUCache &)': cannot convert argument 1 from 'const size_t' to 'const mitsuba::LRUCache &'
src\volume\volcache.cpp(181): note: Reason: cannot convert from 'const size_t' to 'const mitsuba::LRUCache'
src\volume\volcache.cpp(181): note: No constructor could take the source type, or constructor overload resolution was ambiguous
include\mitsuba/core/lrucache.h(153): note: see declaration of 'mitsuba::LRUCache::LRUCache'
_1
修改为std::placehodlers::_1
即可, 但需要修改多个地方libOpenEXR
, 在config.py
中将OEXRLIB
修改为: OEXRLIB = ['OpenEXR-3_1', 'IlmThread-3_1', 'Iex-3_1', 'zlib']
config.py
, GLLIB
的第三个元素从glew32mx
修改为glew32