forked from bartvdbraak/blender
merge from trunk at r31523
This commit is contained in:
commit
82432d0d99
@ -294,9 +294,9 @@ IF(UNIX AND NOT APPLE)
|
||||
SET(EXPAT_LIB expat)
|
||||
ENDIF (WITH_OPENCOLLADA)
|
||||
|
||||
FIND_PACKAGE(X11 REQUIRED)
|
||||
|
||||
# Could use ${X11_Xinput_LIB} ${X11_X11_LIB} too
|
||||
SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++ -lX11")
|
||||
SET(LLIBS "-lutil -lc -lm -lpthread -lstdc++ ${X11_X11_LIB} ${X11_Xinput_LIB}")
|
||||
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
# BSD's dont use libdl.so
|
||||
@ -415,11 +415,19 @@ IF(WIN32)
|
||||
SET(CMAKE_CXX_FLAGS "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305" CACHE STRING "MSVC MT C++ flags " FORCE)
|
||||
SET(CMAKE_C_FLAGS "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305" CACHE STRING "MSVC MT C++ flags " FORCE)
|
||||
|
||||
IF(CMAKE_CL_64)
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
ELSE(CMAKE_CL_64)
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /ZI /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "/O2 /Ob2 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
SET(CMAKE_CXX_FLAGS_MINSIZEREL "/O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
IF(CMAKE_CL_64)
|
||||
SET(CMAKE_C_FLAGS_DEBUG "/D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
ELSE(CMAKE_CL_64)
|
||||
SET(CMAKE_C_FLAGS_DEBUG "/D_DEBUG /Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /ZI /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
SET(CMAKE_C_FLAGS_RELEASE "/O2 /Ob2 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
SET(CMAKE_C_FLAGS_MINSIZEREL "/O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
|
||||
@ -873,7 +881,7 @@ ENDIF(WITH_RAYOPTIMIZATION)
|
||||
IF(WITH_IMAGE_OPENJPEG)
|
||||
set(OPENJPEG ${CMAKE_SOURCE_DIR}/extern/libopenjpeg)
|
||||
set(OPENJPEG_INC ${OPENJPEG})
|
||||
set(OPENJPEG_LIb extern_libopenjpeg)
|
||||
set(OPENJPEG_LIb extern_openjpeg)
|
||||
ENDIF(WITH_IMAGE_OPENJPEG)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
@ -406,12 +406,12 @@ thestatlibs, thelibincs = B.setup_staticlibs(env)
|
||||
thesyslibs = B.setup_syslibs(env)
|
||||
|
||||
if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']:
|
||||
env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist + thestatlibs, [], thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
|
||||
env.BlenderProg(B.root_build_dir, "blender", mainlist + thestatlibs + dobj, thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
|
||||
if env['WITH_BF_PLAYER']:
|
||||
playerlist = B.create_blender_liblist(env, 'player')
|
||||
playerlist += B.create_blender_liblist(env, 'intern')
|
||||
playerlist += B.create_blender_liblist(env, 'extern')
|
||||
env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist, [], thestatlibs + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer')
|
||||
env.BlenderProg(B.root_build_dir, "blenderplayer", playerlist, thestatlibs + dobj + thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer')
|
||||
|
||||
##### Now define some targets
|
||||
|
||||
|
119
build_files/cmake/example_scripts/make_quicky.py
Executable file
119
build_files/cmake/example_scripts/make_quicky.py
Executable file
@ -0,0 +1,119 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
def print_help(targets):
|
||||
print("CMake quicky wrapper, no valid targets given.")
|
||||
print(" * targets can contain a subset of the full target name.")
|
||||
print(" * arguments with a '-' prefix are passed onto make.")
|
||||
print(" * this must run from the cmake build dir")
|
||||
print(" * alias this with a short command for speedy access, in bash:")
|
||||
print(" alias mk='../blender/build_files/cmake/example_scripts/make_quicky.py'")
|
||||
print("")
|
||||
print(" eg: make_quicky.py -j3 extern python")
|
||||
print(" ...will execute")
|
||||
print(" make -j3 extern_binreloc extern_glew bf_python bf_python_ext blender/fast")
|
||||
print("")
|
||||
print("Target List:")
|
||||
for t in targets:
|
||||
print(" %s" % t)
|
||||
print("...exiting")
|
||||
|
||||
|
||||
def main():
|
||||
targets = set()
|
||||
|
||||
# collect targets
|
||||
file = open("Makefile", "r")
|
||||
for line in file:
|
||||
line = line.rstrip()
|
||||
if not line or line[0] in ". \t@$#":
|
||||
continue
|
||||
|
||||
line = line.split("#", 1)[0]
|
||||
if ":" not in line:
|
||||
continue
|
||||
|
||||
line = line.split(":", 1)[0]
|
||||
|
||||
if "/" in line: # cmake terget options, dont need these
|
||||
continue
|
||||
|
||||
targets.add(line)
|
||||
file.close()
|
||||
|
||||
|
||||
# remove cmake targets
|
||||
bad = set([
|
||||
"help",
|
||||
"clean",
|
||||
"all",
|
||||
"preinstall",
|
||||
"install",
|
||||
"default_target",
|
||||
"edit_cache",
|
||||
"cmake_force",
|
||||
"rebuild_cache",
|
||||
"depend",
|
||||
"cmake_check_build_system",
|
||||
])
|
||||
|
||||
targets -= set(bad)
|
||||
|
||||
|
||||
# parse args
|
||||
targets = list(targets)
|
||||
targets.sort()
|
||||
|
||||
import sys
|
||||
if len(sys.argv) == 1:
|
||||
print_help(targets)
|
||||
return
|
||||
|
||||
targets_new = []
|
||||
args = []
|
||||
for arg in sys.argv[1:]:
|
||||
if arg[0] in "/-":
|
||||
args.append(arg)
|
||||
else:
|
||||
found = False
|
||||
for t in targets:
|
||||
if arg in t and t not in targets_new:
|
||||
targets_new.append(t)
|
||||
found = True
|
||||
|
||||
if not found:
|
||||
print("Error '%s' not found in...")
|
||||
for t in targets:
|
||||
print(" %s" % t)
|
||||
print("...aborting.")
|
||||
return
|
||||
|
||||
# execute
|
||||
cmd = "make %s %s blender/fast" % (" ".join(args), " ".join(targets_new))
|
||||
print("cmake building with targets: %s" % " ".join(targets_new))
|
||||
print("executing: %s" % cmd)
|
||||
|
||||
import os
|
||||
os.system(cmd)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -57,7 +57,6 @@ BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
|
||||
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
|
||||
# BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
|
||||
|
||||
|
||||
WITH_BF_DDS = True
|
||||
|
||||
WITH_BF_JPEG = True
|
||||
@ -87,7 +86,7 @@ BF_GETTEXT_INC = '${BF_GETTEXT}/include'
|
||||
BF_GETTEXT_LIB = 'gettextlib'
|
||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||
|
||||
WITH_BF_GAMEENGINE = True
|
||||
WITH_BF_GAMEENGINE = False
|
||||
WITH_BF_PLAYER = True
|
||||
|
||||
WITH_BF_BULLET = True
|
||||
@ -100,7 +99,8 @@ BF_FREETYPE = '/usr/local'
|
||||
BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
|
||||
WITH_BF_QUICKTIME = True # -DWITH_QUICKTIME
|
||||
### XXX Find what this actually wants; it doesn't want libquicktime.
|
||||
WITH_BF_QUICKTIME = False # -DWITH_QUICKTIME
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||
|
||||
@ -195,7 +195,7 @@ CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare']
|
||||
|
||||
##FIX_STUBS_WARNINGS = -Wno-unused
|
||||
|
||||
LLIBS = ['util', 'c', 'm', 'dl', 'pthread', 'stdc++']
|
||||
LLIBS = ['util', 'c', 'm', 'pthread', 'stdc++']
|
||||
##LOPTS = --dynamic
|
||||
##DYNLDFLAGS = -shared $(LDFLAGS)
|
||||
|
||||
|
@ -57,7 +57,6 @@ BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
|
||||
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
|
||||
# BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
|
||||
|
||||
|
||||
WITH_BF_DDS = True
|
||||
|
||||
WITH_BF_JPEG = True
|
||||
@ -87,7 +86,7 @@ BF_GETTEXT_INC = '${BF_GETTEXT}/include'
|
||||
BF_GETTEXT_LIB = 'gettextlib'
|
||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||
|
||||
WITH_BF_GAMEENGINE = True
|
||||
WITH_BF_GAMEENGINE = False
|
||||
WITH_BF_PLAYER = True
|
||||
|
||||
WITH_BF_BULLET = True
|
||||
@ -100,7 +99,8 @@ BF_FREETYPE = '/usr/local'
|
||||
BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
|
||||
WITH_BF_QUICKTIME = True # -DWITH_QUICKTIME
|
||||
### XXX Find what this actually wants; it doesn't want libquicktime.
|
||||
WITH_BF_QUICKTIME = False # -DWITH_QUICKTIME
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||
|
||||
@ -195,7 +195,7 @@ CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare']
|
||||
|
||||
##FIX_STUBS_WARNINGS = -Wno-unused
|
||||
|
||||
LLIBS = ['util', 'c', 'm', 'dl', 'pthread', 'stdc++']
|
||||
LLIBS = ['util', 'c', 'm', 'pthread', 'stdc++']
|
||||
##LOPTS = --dynamic
|
||||
##DYNLDFLAGS = -shared $(LDFLAGS)
|
||||
|
||||
|
@ -57,7 +57,6 @@ BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
|
||||
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
|
||||
# BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
|
||||
|
||||
|
||||
WITH_BF_DDS = True
|
||||
|
||||
WITH_BF_JPEG = True
|
||||
@ -87,7 +86,7 @@ BF_GETTEXT_INC = '${BF_GETTEXT}/include'
|
||||
BF_GETTEXT_LIB = 'gettextlib'
|
||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||
|
||||
WITH_BF_GAMEENGINE = True
|
||||
WITH_BF_GAMEENGINE = False
|
||||
WITH_BF_PLAYER = True
|
||||
|
||||
WITH_BF_BULLET = True
|
||||
@ -100,7 +99,8 @@ BF_FREETYPE = '/usr/local'
|
||||
BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
|
||||
WITH_BF_QUICKTIME = True # -DWITH_QUICKTIME
|
||||
### XXX Find what this actually wants; it doesn't want libquicktime.
|
||||
WITH_BF_QUICKTIME = False # -DWITH_QUICKTIME
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||
|
||||
@ -195,7 +195,7 @@ CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare']
|
||||
|
||||
##FIX_STUBS_WARNINGS = -Wno-unused
|
||||
|
||||
LLIBS = ['util', 'c', 'm', 'dl', 'pthread', 'stdc++']
|
||||
LLIBS = ['util', 'c', 'm', 'pthread', 'stdc++']
|
||||
##LOPTS = --dynamic
|
||||
##DYNLDFLAGS = -shared $(LDFLAGS)
|
||||
|
||||
|
@ -84,6 +84,8 @@ BF_GETTEXT = '/usr'
|
||||
BF_GETTEXT_INC = '${BF_GETTEXT}/include'
|
||||
BF_GETTEXT_LIB = 'gettextlib'
|
||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||
#WITH_BF_GETTEXT_STATIC = True
|
||||
#BF_GETTEXT_LIB_STATIC = '${BF_GETTEXT}/lib/libgettextlib.a'
|
||||
|
||||
WITH_BF_GAMEENGINE = True
|
||||
WITH_BF_PLAYER = False
|
||||
@ -97,6 +99,8 @@ BF_BULLET_LIB = 'extern_bullet'
|
||||
BF_FREETYPE = '/usr'
|
||||
BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
#WITH_BF_FREETYPE_STATIC = True
|
||||
#BF_FREETYPE_LIB_STATIC = '${BF_FREETYPE}/lib/libfreetype.a'
|
||||
|
||||
WITH_BF_QUICKTIME = False # -DWITH_QUICKTIME
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
@ -116,6 +120,8 @@ BF_FFMPEG = '/usr'
|
||||
BF_FFMPEG_LIB = 'avformat avcodec swscale avutil avdevice'
|
||||
BF_FFMPEG_INC = '${BF_FFMPEG}/include'
|
||||
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
|
||||
#WITH_BF_STATICFFMPEG = True
|
||||
#BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH/libavcodec.a ${BF_FFMPEG_LIBPATH}/libswscale.a ${BF_FFMPEG_LIBPATH}/libavutil.a ${BF_FFMPEG_LIBPATH}/libavdevice.a'
|
||||
|
||||
# enable ogg, vorbis and theora in ffmpeg
|
||||
WITH_BF_OGG = False # -DWITH_OGG
|
||||
|
@ -23,6 +23,7 @@ import sys
|
||||
import zipfile
|
||||
import shutil
|
||||
import cStringIO
|
||||
import platform
|
||||
|
||||
from SCons.Script.SConscript import SConsEnvironment
|
||||
import SCons.Action
|
||||
@ -153,8 +154,14 @@ def setup_staticlibs(lenv):
|
||||
libincs += Split(lenv['BF_TIFF_LIBPATH'])
|
||||
if lenv['WITH_BF_FFTW3']:
|
||||
libincs += Split(lenv['BF_FFTW3_LIBPATH'])
|
||||
if lenv['WITH_BF_FFMPEG'] and lenv['WITH_BF_STATICFFMPEG']:
|
||||
statlibs += Split(lenv['BF_FFMPEG_LIB_STATIC'])
|
||||
if lenv['WITH_BF_INTERNATIONAL']:
|
||||
libincs += Split(lenv['BF_GETTEXT_LIBPATH'])
|
||||
if lenv['WITH_BF_GETTEXT_STATIC']:
|
||||
statlibs += Split(lenv['BF_GETTEXT_LIB_STATIC'])
|
||||
if lenv['WITH_BF_FREETYPE_STATIC']:
|
||||
statlibs += Split(lenv['BF_FREETYPE_LIB_STATIC'])
|
||||
if lenv['WITH_BF_OPENAL']:
|
||||
libincs += Split(lenv['BF_OPENAL_LIBPATH'])
|
||||
if lenv['WITH_BF_STATICOPENAL']:
|
||||
@ -195,13 +202,14 @@ def setup_syslibs(lenv):
|
||||
lenv['BF_LIBSAMPLERATE_LIB']
|
||||
]
|
||||
|
||||
if not lenv['WITH_BF_FREETYPE_STATIC']:
|
||||
syslibs += Split(lenv['BF_FREETYPE_LIB'])
|
||||
if lenv['WITH_BF_PYTHON'] and not lenv['WITH_BF_STATICPYTHON']:
|
||||
if lenv['BF_DEBUG'] and lenv['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw'):
|
||||
syslibs.append(lenv['BF_PYTHON_LIB']+'_d')
|
||||
else:
|
||||
syslibs.append(lenv['BF_PYTHON_LIB'])
|
||||
if lenv['WITH_BF_INTERNATIONAL']:
|
||||
if lenv['WITH_BF_INTERNATIONAL'] and not lenv['WITH_BF_GETTEXT_STATIC']:
|
||||
syslibs += Split(lenv['BF_GETTEXT_LIB'])
|
||||
if lenv['WITH_BF_OPENAL']:
|
||||
if not lenv['WITH_BF_STATICOPENAL']:
|
||||
@ -218,7 +226,7 @@ def setup_syslibs(lenv):
|
||||
syslibs += Split(lenv['BF_OPENEXR_LIB'])
|
||||
if lenv['WITH_BF_TIFF']:
|
||||
syslibs += Split(lenv['BF_TIFF_LIB'])
|
||||
if lenv['WITH_BF_FFMPEG']:
|
||||
if lenv['WITH_BF_FFMPEG'] and not lenv['WITH_BF_STATICFFMPEG']:
|
||||
syslibs += Split(lenv['BF_FFMPEG_LIB'])
|
||||
if lenv['WITH_BF_OGG']:
|
||||
syslibs += Split(lenv['BF_OGG_LIB'])
|
||||
@ -269,15 +277,21 @@ def buildinfo(lenv, build_type):
|
||||
build_date = time.strftime ("%Y-%m-%d")
|
||||
build_time = time.strftime ("%H:%M:%S")
|
||||
build_rev = os.popen('svnversion').read()[:-1] # remove \n
|
||||
if build_rev == '':
|
||||
build_rev = '<UNKNOWN>'
|
||||
if lenv['BF_DEBUG']:
|
||||
build_type = "Debug"
|
||||
else:
|
||||
build_type = "Release"
|
||||
|
||||
obj = []
|
||||
if lenv['BF_BUILDINFO']:
|
||||
lenv.Append (CPPDEFINES = ['BUILD_TIME=\'"%s"\''%(build_time),
|
||||
'BUILD_DATE=\'"%s"\''%(build_date),
|
||||
'BUILD_TYPE=\'"dynamic"\'',
|
||||
'BUILD_REV=\'"%s"\''%(build_rev),
|
||||
lenv.Append (CPPDEFINES = ['BUILD_TIME="%s"'%(build_time),
|
||||
'BUILD_DATE="%s"'%(build_date),
|
||||
'BUILD_TYPE="%s"'%(build_type),
|
||||
'BUILD_REV="%s"'%(build_rev),
|
||||
'NAN_BUILDINFO',
|
||||
'BUILD_PLATFORM=\'"%s"\''%(sys.platform)])
|
||||
'BUILD_PLATFORM="%s:%s"'%(platform.system(), platform.architecture()[0])])
|
||||
obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type,
|
||||
[root_build_dir+'source/creator/buildinfo.c'])]
|
||||
return obj
|
||||
@ -463,6 +477,9 @@ def WinPyBundle(target=None, source=None, env=None):
|
||||
py_zip= env.subst( env['LCGDIR'] )
|
||||
if py_zip[0]=='#':
|
||||
py_zip= py_zip[1:]
|
||||
if env['BF_DEBUG']:
|
||||
py_zip+= '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '_d.zip'
|
||||
else:
|
||||
py_zip+= '/release/python' + env['BF_PYTHON_VERSION'].replace('.','') + '.zip'
|
||||
|
||||
py_target = env.subst( env['BF_INSTALLDIR'] )
|
||||
@ -722,7 +739,7 @@ class BlenderEnvironment(SConsEnvironment):
|
||||
# note: libs is a global
|
||||
add_lib_to_dict(self, libs, libtype, libname, priority)
|
||||
|
||||
def BlenderProg(self=None, builddir=None, progname=None, sources=None, includes=None, libs=None, libpath=None, binarykind=''):
|
||||
def BlenderProg(self=None, builddir=None, progname=None, sources=None, libs=None, libpath=None, binarykind=''):
|
||||
global vcp
|
||||
print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
|
||||
lenv = self.Clone()
|
||||
@ -748,7 +765,6 @@ class BlenderEnvironment(SConsEnvironment):
|
||||
lenv.Append(LINKFLAGS = lenv['BF_OPENGL_LINKFLAGS'])
|
||||
if lenv['BF_PROFILE']:
|
||||
lenv.Append(LINKFLAGS = lenv['BF_PROFILE_LINKFLAGS'])
|
||||
lenv.Append(CPPPATH=includes)
|
||||
if root_build_dir[0]==os.sep or root_build_dir[1]==':':
|
||||
lenv.Append(LIBPATH=root_build_dir + '/lib')
|
||||
lenv.Append(LIBPATH=libpath)
|
||||
|
@ -38,6 +38,7 @@ def validate_arguments(args, bc):
|
||||
'WITH_BF_OPENEXR', 'BF_OPENEXR', 'BF_OPENEXR_INC', 'BF_OPENEXR_LIB', 'BF_OPENEXR_LIBPATH', 'WITH_BF_STATICOPENEXR', 'BF_OPENEXR_LIB_STATIC',
|
||||
'WITH_BF_DDS', 'WITH_BF_CINEON', 'WITH_BF_HDR',
|
||||
'WITH_BF_FFMPEG', 'BF_FFMPEG_LIB','BF_FFMPEG_EXTRA', 'BF_FFMPEG', 'BF_FFMPEG_INC',
|
||||
'WITH_BF_STATICFFMPEG', 'BF_FFMPEG_LIB_STATIC',
|
||||
'WITH_BF_OGG', 'BF_OGG', 'BF_OGG_LIB',
|
||||
'WITH_BF_JPEG', 'BF_JPEG', 'BF_JPEG_INC', 'BF_JPEG_LIB', 'BF_JPEG_LIBPATH',
|
||||
'WITH_BF_OPENJPEG', 'BF_OPENJPEG', 'BF_OPENJPEG_INC', 'BF_OPENJPEG_LIB', 'BF_OPENJPEG_LIBPATH',
|
||||
@ -46,11 +47,11 @@ def validate_arguments(args, bc):
|
||||
'WITH_BF_TIFF', 'BF_TIFF', 'BF_TIFF_INC', 'BF_TIFF_LIB', 'BF_TIFF_LIBPATH',
|
||||
'WITH_BF_ZLIB', 'BF_ZLIB', 'BF_ZLIB_INC', 'BF_ZLIB_LIB', 'BF_ZLIB_LIBPATH',
|
||||
'WITH_BF_INTERNATIONAL',
|
||||
'BF_GETTEXT', 'BF_GETTEXT_INC', 'BF_GETTEXT_LIB', 'BF_GETTEXT_LIBPATH',
|
||||
'BF_GETTEXT', 'BF_GETTEXT_INC', 'BF_GETTEXT_LIB', 'WITH_BF_GETTEXT_STATIC', 'BF_GETTEXT_LIB_STATIC', 'BF_GETTEXT_LIBPATH',
|
||||
'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH',
|
||||
'WITH_BF_GAMEENGINE', 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB',
|
||||
'BF_WINTAB', 'BF_WINTAB_INC',
|
||||
'WITH_BF_FREETYPE', 'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH',
|
||||
'WITH_BF_FREETYPE', 'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH', 'BF_FREETYPE_LIB_STATIC', 'WITH_BF_FREETYPE_STATIC',
|
||||
'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH',
|
||||
'WITH_BF_FFTW3', 'BF_FFTW3', 'BF_FFTW3_INC', 'BF_FFTW3_LIB', 'BF_FFTW3_LIBPATH',
|
||||
'WITH_BF_STATICOPENGL', 'BF_OPENGL', 'BF_OPENGL_INC', 'BF_OPENGL_LIB', 'BF_OPENGL_LIBPATH', 'BF_OPENGL_LIB_STATIC',
|
||||
@ -236,6 +237,8 @@ def read_opts(env, cfg, args):
|
||||
|
||||
('BF_FFMPEG_INC', 'FFMPEG includes', ''),
|
||||
('BF_FFMPEG_LIBPATH', 'FFMPEG library path', ''),
|
||||
(BoolVariable('WITH_BF_STATICFFMPEG', 'Use static FFMPEG if true', False)),
|
||||
('BF_FFMPEG_LIB_STATIC', 'Static FFMPEG libraries', ''),
|
||||
|
||||
(BoolVariable('WITH_BF_OGG', 'Use OGG, THEORA, VORBIS in FFMPEG if true',
|
||||
False)),
|
||||
@ -289,6 +292,8 @@ def read_opts(env, cfg, args):
|
||||
('BF_GETTEXT', 'gettext base path', ''),
|
||||
('BF_GETTEXT_INC', 'gettext include path', ''),
|
||||
('BF_GETTEXT_LIB', 'gettext library', ''),
|
||||
(BoolVariable('WITH_BF_GETTEXT_STATIC', 'Use static gettext library if true', False)),
|
||||
('BF_GETTEXT_LIB_STATIC', 'static gettext library', ''),
|
||||
('BF_GETTEXT_LIBPATH', 'gettext library path', ''),
|
||||
|
||||
(BoolVariable('WITH_BF_ICONV', 'Use iconv if true', True)),
|
||||
@ -309,29 +314,14 @@ def read_opts(env, cfg, args):
|
||||
('BF_CXX', 'c++ base path for libstdc++, only used when static linking', ''),
|
||||
(BoolVariable('WITH_BF_STATICCXX', 'static link to stdc++', False)),
|
||||
('BF_CXX_LIB_STATIC', 'static library path for stdc++', ''),
|
||||
##
|
||||
##WITH_BF_NSPR = True
|
||||
##BF_NSPR = $(LCGDIR)/nspr
|
||||
##BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr
|
||||
##BF_NSPR_LIB =
|
||||
### Uncomment the following line to use Mozilla inplace of netscape
|
||||
##CPPFLAGS += -DMOZ_NOT_NET
|
||||
### Location of MOZILLA/Netscape header files...
|
||||
##BF_MOZILLA = $(LCGDIR)/mozilla
|
||||
##BF_MOZILLA_INC = -I$(BF_MOZILLA)/include/mozilla/nspr -I$(BF_MOZILLA)/include/mozilla -I$(BF_MOZILLA)/include/mozilla/xpcom -I$(BF_MOZILLA)/include/mozilla/idl
|
||||
##BF_MOZILLA_LIB =
|
||||
### Will fall back to look in BF_MOZILLA_INC/nspr and BF_MOZILLA_LIB
|
||||
### if this is not set.
|
||||
##
|
||||
### Be paranoid regarding library creation (do not update archives)
|
||||
##BF_PARANOID = True
|
||||
##
|
||||
### enable freetype2 support for text objects
|
||||
|
||||
(BoolVariable('WITH_BF_FREETYPE', 'Use FreeType2 if true', True)),
|
||||
('BF_FREETYPE', 'Freetype base path', ''),
|
||||
('BF_FREETYPE_INC', 'Freetype include path', ''),
|
||||
('BF_FREETYPE_LIB', 'Freetype library', ''),
|
||||
('BF_FREETYPE_LIBPATH', 'Freetype library path', ''),
|
||||
(BoolVariable('WITH_BF_FREETYPE_STATIC', 'Use Static Freetype if true', False)),
|
||||
('BF_FREETYPE_LIB_STATIC', 'Static Freetype library', ''),
|
||||
|
||||
(BoolVariable('WITH_BF_OPENMP', 'Use OpenMP if true', False)),
|
||||
('BF_OPENMP', 'Base path to OpenMP (used when cross-compiling with older versions of WinGW)', ''),
|
||||
|
@ -32,4 +32,4 @@ license@blender.org for further information.
|
||||
|
||||
Ton Roosendaal
|
||||
Chairman Blender Foundation.
|
||||
June 2005
|
||||
June 2005
|
||||
|
@ -1390,4 +1390,4 @@ Radoslav Dejanovic
|
||||
James H. Cloos, Jr.
|
||||
Karl Erlandsen (LethalSideParting)
|
||||
Kari Pulli
|
||||
Dave Shemano
|
||||
Dave Shemano
|
||||
|
@ -24,12 +24,13 @@ btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int
|
||||
m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE;
|
||||
m_unscaledPoints.resize(numPoints);
|
||||
|
||||
unsigned char* pointsBaseAddress = (unsigned char*)points;
|
||||
unsigned char* pointsAddress = (unsigned char*)points;
|
||||
|
||||
for (int i=0;i<numPoints;i++)
|
||||
{
|
||||
btVector3* point = (btVector3*)(pointsBaseAddress + i*stride);
|
||||
m_unscaledPoints[i] = point[0];
|
||||
btScalar* point = (btScalar*)pointsAddress;
|
||||
m_unscaledPoints[i] = btVector3(point[0], point[1], point[2]);
|
||||
pointsAddress += stride;
|
||||
}
|
||||
|
||||
recalcLocalAabb();
|
||||
|
2
extern/libopenjpeg/CMakeLists.txt
vendored
2
extern/libopenjpeg/CMakeLists.txt
vendored
@ -28,5 +28,5 @@ SET(INC . src)
|
||||
|
||||
FILE(GLOB SRC *.c except t1_generate_luts.c)
|
||||
ADD_DEFINITIONS(-DWITH_OPENJPEG)
|
||||
BLENDERLIB(extern_libopenjpeg "${SRC}" "${INC}")
|
||||
BLENDERLIB(extern_openjpeg "${SRC}" "${INC}")
|
||||
#, libtype=['international','player'], priority=[5, 210])
|
||||
|
5
extern/lzma/CMakeLists.txt
vendored
5
extern/lzma/CMakeLists.txt
vendored
@ -28,7 +28,4 @@ SET(INC . )
|
||||
|
||||
FILE(GLOB SRC ./*.c)
|
||||
|
||||
|
||||
|
||||
BLENDERLIB(bf_lzma "${SRC}" "${INC}")
|
||||
#, libtype='blender', priority = 0 )
|
||||
BLENDERLIB(extern_lzma "${SRC}" "${INC}")
|
||||
|
2
extern/lzma/SConscript
vendored
2
extern/lzma/SConscript
vendored
@ -6,4 +6,4 @@ sources = env.Glob('./*.c')
|
||||
defs = ''
|
||||
incs = ' . '
|
||||
|
||||
env.BlenderLib ('bf_lzma', sources, Split(incs), Split(defs), libtype=['intern'], priority=[40] )
|
||||
env.BlenderLib ('extern_lzma', sources, Split(incs), Split(defs), libtype=['intern'], priority=[40] )
|
||||
|
2
extern/lzo/CMakeLists.txt
vendored
2
extern/lzo/CMakeLists.txt
vendored
@ -30,5 +30,5 @@ FILE(GLOB SRC minilzo/*.c)
|
||||
|
||||
|
||||
|
||||
BLENDERLIB(bf_minilzo "${SRC}" "${INC}")
|
||||
BLENDERLIB(extern_minilzo "${SRC}" "${INC}")
|
||||
#, libtype='blender', priority = 0 )
|
||||
|
2
extern/lzo/SConscript
vendored
2
extern/lzo/SConscript
vendored
@ -6,4 +6,4 @@ sources = env.Glob('minilzo/*.c')
|
||||
defs = ''
|
||||
incs = ' include '
|
||||
|
||||
env.BlenderLib ('bf_minilzo', sources, Split(incs), Split(defs), libtype=['intern'], priority=[40] )
|
||||
env.BlenderLib ('extern_minilzo', sources, Split(incs), Split(defs), libtype=['intern'], priority=[40] )
|
||||
|
@ -28,5 +28,5 @@ SET(INC . intern extern ../moto/include ../container ../memutil ../../source/ble
|
||||
|
||||
FILE(GLOB SRC intern/*.cpp)
|
||||
|
||||
BLENDERLIB(blender_bop "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_bop "${SRC}" "${INC}")
|
||||
#, libtype='common', priority=5 )
|
||||
|
@ -8,7 +8,7 @@ incs += ' ../../source/blender/makesdna ../../intern/guardedalloc'
|
||||
incs += ' ../../source/blender/blenlib'
|
||||
|
||||
if (env['OURPLATFORM'] == 'win32-mingw'):
|
||||
env.BlenderLib ('blender_bop', sources, Split(incs) , [], libtype='intern', priority = 5 )
|
||||
env.BlenderLib ('bf_intern_bop', sources, Split(incs) , [], libtype='intern', priority = 5 )
|
||||
else:
|
||||
env.BlenderLib ('blender_bop', sources, Split(incs) , [], libtype='intern', priority = 5 )
|
||||
env.BlenderLib ('bf_intern_bop', sources, Split(incs) , [], libtype='intern', priority = 5 )
|
||||
|
||||
|
@ -28,5 +28,5 @@ SET(INC intern ../container ../moto/include ../memutil)
|
||||
|
||||
FILE(GLOB SRC intern/*.cpp)
|
||||
|
||||
BLENDERLIB(blender_BSP "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_bsp "${SRC}" "${INC}")
|
||||
#, libtype='core', priority=15 )
|
||||
|
@ -5,5 +5,5 @@ sources = env.Glob('intern/*.cpp')
|
||||
|
||||
incs = 'intern ../container ../moto/include ../memutil'
|
||||
|
||||
env.BlenderLib ('blender_BSP', sources, Split(incs), [], libtype='core', priority=200 )
|
||||
env.BlenderLib ('bf_intern_bsp', sources, Split(incs), [], libtype='core', priority=200 )
|
||||
|
||||
|
@ -28,5 +28,5 @@ SET(INC .)
|
||||
|
||||
FILE(GLOB SRC intern/*.cpp)
|
||||
|
||||
BLENDERLIB(blender_CTR "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_ctr "${SRC}" "${INC}")
|
||||
#, libtype=['intern'], priority = 10 )
|
||||
|
@ -4,4 +4,4 @@ Import ('env')
|
||||
sources = env.Glob('intern/*.cpp')
|
||||
incs = '.'
|
||||
|
||||
env.BlenderLib ('blender_CTR', sources, Split(incs) , [], libtype='intern', priority = 10 )
|
||||
env.BlenderLib ('bf_intern_ctr', sources, Split(incs) , [], libtype='intern', priority = 10 )
|
||||
|
@ -28,5 +28,5 @@ SET(INC . ../moto/include ../container ../memutil)
|
||||
|
||||
FILE(GLOB SRC intern/*.cpp)
|
||||
|
||||
BLENDERLIB(bf_decimation "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_decimate "${SRC}" "${INC}")
|
||||
#, libtype=['core','common','player'], priority = [10, 20, 25] )
|
||||
|
@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp')
|
||||
|
||||
incs = '. ../moto/include ../container ../memutil'
|
||||
|
||||
env.BlenderLib ('bf_decimation', sources, Split(incs) , [], libtype=['core'], priority = [200] )
|
||||
env.BlenderLib ('bf_intern_decimate', sources, Split(incs) , [], libtype=['core'], priority = [200] )
|
||||
|
@ -37,5 +37,5 @@ IF(WITH_OPENMP)
|
||||
ADD_DEFINITIONS(-DPARALLEL=1)
|
||||
ENDIF(WITH_OPENMP)
|
||||
|
||||
BLENDERLIB_NOLIST(bf_elbeem "${SRC}" "${INC}")
|
||||
BLENDERLIB_NOLIST(bf_intern_elbeem "${SRC}" "${INC}")
|
||||
#, libtype='blender', priority=0 )
|
||||
|
@ -19,4 +19,4 @@ if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||
incs += ' ' + env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC']
|
||||
incs += ' extern '
|
||||
|
||||
env.BlenderLib ('bf_elbeem', sources, Split(incs), Split(defs), libtype='intern', priority=0 )
|
||||
env.BlenderLib ('bf_intern_elbeem', sources, Split(incs), Split(defs), libtype='intern', priority=0 )
|
||||
|
@ -90,5 +90,5 @@ ELSEIF(UNIX)
|
||||
|
||||
ENDIF(APPLE)
|
||||
|
||||
BLENDERLIB(bf_ghost "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_ghost "${SRC}" "${INC}")
|
||||
|
||||
|
@ -60,4 +60,4 @@ if env['BF_GHOST_DEBUG']:
|
||||
incs = '. ../string #extern/glew/include #source/blender/imbuf #source/blender/makesdna ' + env['BF_OPENGL_INC']
|
||||
if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
|
||||
incs = env['BF_WINTAB_INC'] + ' ' + incs
|
||||
env.BlenderLib ('bf_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] )
|
||||
env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] )
|
||||
|
@ -212,4 +212,4 @@ bool GHOST_WindowManager::getAnyModifiedState()
|
||||
}
|
||||
|
||||
return isAnyModified;
|
||||
}
|
||||
}
|
||||
|
@ -28,10 +28,10 @@ SET(INC .)
|
||||
|
||||
FILE(GLOB SRC intern/*.c)
|
||||
|
||||
BLENDERLIB(bf_guardedalloc "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_guardedalloc "${SRC}" "${INC}")
|
||||
|
||||
# Override C++ alloc optional
|
||||
IF(WITH_CXX_GUARDEDALLOC)
|
||||
FILE(GLOB SRC cpp/*.cpp)
|
||||
BLENDERLIB(bf_guardedalloc_cpp "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_guardedalloc_cpp "${SRC}" "${INC}")
|
||||
ENDIF(WITH_CXX_GUARDEDALLOC)
|
||||
|
@ -5,4 +5,4 @@ Import('env')
|
||||
sources = env.Glob('intern/*.c')
|
||||
incs = '.'
|
||||
|
||||
env.BlenderLib ('bf_guardedalloc', sources, Split(incs), defines=[], libtype=['intern','player'], priority = [5,150] )
|
||||
env.BlenderLib ('bf_intern_guardedalloc', sources, Split(incs), defines=[], libtype=['intern','player'], priority = [5,150] )
|
||||
|
@ -28,5 +28,5 @@ SET(INC intern ../moto/include ../memutil)
|
||||
|
||||
FILE(GLOB SRC intern/*.cpp)
|
||||
|
||||
BLENDERLIB(bf_IK "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_ik "${SRC}" "${INC}")
|
||||
#, libtype=['blender'], priority = [10] )
|
||||
|
@ -5,5 +5,5 @@ sources = env.Glob('intern/*.cpp')
|
||||
|
||||
incs = 'intern ../moto/include ../memutil'
|
||||
|
||||
env.BlenderLib ('bf_IK', sources, Split(incs), [], libtype=['intern','player'], priority=[100,90] )
|
||||
env.BlenderLib ('bf_intern_ik', sources, Split(incs), [], libtype=['intern','player'], priority=[100,90] )
|
||||
|
||||
|
@ -28,5 +28,5 @@ SET(INC ../../extern/Eigen2)
|
||||
|
||||
FILE(GLOB SRC *.cpp kdl/*.cpp kdl/utilities/*.cpp)
|
||||
|
||||
BLENDERLIB(bf_ITASC "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_itasc "${SRC}" "${INC}")
|
||||
#, libtype=['blender'], priority = [10] )
|
||||
|
@ -7,5 +7,5 @@ sources += env.Glob('kdl/utilities/*.cpp')
|
||||
|
||||
incs = '. ../../extern/Eigen2'
|
||||
|
||||
env.BlenderLib ('bf_ITASC', sources, Split(incs), [], libtype=['intern','player'], priority=[20,100] )
|
||||
env.BlenderLib ('bf_intern_itasc', sources, Split(incs), [], libtype=['intern','player'], priority=[20,100] )
|
||||
|
||||
|
@ -28,5 +28,5 @@ SET(INC . ..)
|
||||
|
||||
FILE(GLOB SRC intern/*.cpp)
|
||||
|
||||
BLENDERLIB(bf_memutil "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_memutil "${SRC}" "${INC}")
|
||||
#, libtype=['intern', 'player'], priority = [0, 180] )
|
||||
|
@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp')
|
||||
|
||||
incs = '. ..'
|
||||
|
||||
env.BlenderLib ('bf_memutil', sources, Split(incs), [], libtype=['intern','player'], priority = [0,155] )
|
||||
env.BlenderLib ('bf_intern_memutil', sources, Split(incs), [], libtype=['intern','player'], priority = [0,155] )
|
||||
|
@ -28,5 +28,5 @@ SET(INC include)
|
||||
|
||||
FILE(GLOB SRC intern/*.cpp)
|
||||
|
||||
BLENDERLIB(bf_moto "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_moto "${SRC}" "${INC}")
|
||||
#, libtype=['intern','game','game2','player'], priority = [15, 55, 100, 135] )
|
||||
|
@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp')
|
||||
|
||||
incs = 'include'
|
||||
|
||||
env.BlenderLib ('bf_moto', sources, Split(incs), [], libtype=['intern','player'], priority = [130,95] )
|
||||
env.BlenderLib ('bf_intern_moto', sources, Split(incs), [], libtype=['intern','player'], priority = [130,95] )
|
||||
|
@ -28,6 +28,6 @@ SET(INC extern superlu)
|
||||
|
||||
FILE(GLOB SRC intern/*.c superlu/*.c)
|
||||
|
||||
BLENDERLIB(blender_ONL "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_opennl "${SRC}" "${INC}")
|
||||
#, libtype='core', priority=55 )
|
||||
|
||||
|
@ -6,7 +6,7 @@ sources = env.Glob('intern/*.c') + env.Glob('superlu/*.c')
|
||||
incs = 'extern superlu'
|
||||
|
||||
if (env['OURPLATFORM'] == 'win32-mingw'):
|
||||
env.BlenderLib ('blender_ONL', sources, Split(incs), [], libtype=['core','intern'], priority=[1,80] )
|
||||
env.BlenderLib ('bf_intern_opennl', sources, Split(incs), [], libtype=['core','intern'], priority=[1,80] )
|
||||
else:
|
||||
env.BlenderLib ('blender_ONL', sources, Split(incs), [], libtype=['core'], priority=[55] )
|
||||
env.BlenderLib ('bf_intern_opennl', sources, Split(incs), [], libtype=['core'], priority=[55] )
|
||||
|
||||
|
@ -38,5 +38,5 @@ IF(WITH_FFTW3)
|
||||
ENDIF(WITH_FFTW3)
|
||||
|
||||
|
||||
BLENDERLIB(bf_smoke "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_smoke "${SRC}" "${INC}")
|
||||
#, libtype='blender', priority = 0 )
|
||||
|
@ -19,4 +19,4 @@ if env['WITH_BF_FFTW3']:
|
||||
defs += ' FFTW3=1'
|
||||
incs += env['BF_FFTW3_INC']
|
||||
|
||||
env.BlenderLib ('bf_smoke', sources, Split(incs), Split(defs), libtype=['intern'], priority=[40] )
|
||||
env.BlenderLib ('bf_intern_smoke', sources, Split(incs), Split(defs), libtype=['intern'], priority=[40] )
|
||||
|
@ -28,5 +28,5 @@ SET(INC .)
|
||||
|
||||
FILE(GLOB SRC intern/*.cpp)
|
||||
|
||||
BLENDERLIB(bf_string "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_intern_string "${SRC}" "${INC}")
|
||||
#, libtype=['core', 'player'], priority = [30,10] )
|
||||
|
@ -4,4 +4,4 @@ Import ('env')
|
||||
sources = env.Glob('intern/*.cpp')
|
||||
incs = '.'
|
||||
|
||||
env.BlenderLib ('bf_string', sources, Split(incs), [], libtype=['intern','player'], priority = [50,10] )
|
||||
env.BlenderLib ('bf_intern_string', sources, Split(incs), [], libtype=['intern','player'], priority = [50,10] )
|
||||
|
@ -1,327 +0,0 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
import bpy
|
||||
|
||||
__author__ = "Bruce Merry"
|
||||
__version__ = "0.93"
|
||||
__bpydoc__ = """\
|
||||
This script exports Stanford PLY files from Blender. It supports normals,
|
||||
colours, and texture coordinates per face or per vertex.
|
||||
Only one mesh can be exported at a time.
|
||||
"""
|
||||
|
||||
# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
# Vector rounding se we can use as keys
|
||||
#
|
||||
# Updated on Aug 11, 2008 by Campbell Barton
|
||||
# - added 'comment' prefix to comments - Needed to comply with the PLY spec.
|
||||
#
|
||||
# Updated on Jan 1, 2007 by Gabe Ghearing
|
||||
# - fixed normals so they are correctly smooth/flat
|
||||
# - fixed crash when the model doesn't have uv coords or vertex colors
|
||||
# - fixed crash when the model has vertex colors but doesn't have uv coords
|
||||
# - changed float32 to float and uint8 to uchar for compatibility
|
||||
# Errata/Notes as of Jan 1, 2007
|
||||
# - script exports texture coords if they exist even if TexFace isn't selected (not a big deal to me)
|
||||
# - ST(R) should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
|
||||
#
|
||||
# Updated on Jan 3, 2007 by Gabe Ghearing
|
||||
# - fixed "sticky" vertex UV exporting
|
||||
# - added pupmenu to enable/disable exporting normals, uv coords, and colors
|
||||
# Errata/Notes as of Jan 3, 2007
|
||||
# - ST(R) coords should probably be renamed UV(T) like in most PLY files (importer needs to be updated to take either)
|
||||
# - edges should be exported since PLY files support them
|
||||
# - code is getting spaghettish, it should be refactored...
|
||||
#
|
||||
|
||||
|
||||
def rvec3d(v):
|
||||
return round(v[0], 6), round(v[1], 6), round(v[2], 6)
|
||||
|
||||
|
||||
def rvec2d(v):
|
||||
return round(v[0], 6), round(v[1], 6)
|
||||
|
||||
|
||||
def write(filename, scene, ob, \
|
||||
EXPORT_APPLY_MODIFIERS=True,\
|
||||
EXPORT_NORMALS=True,\
|
||||
EXPORT_UV=True,\
|
||||
EXPORT_COLORS=True):
|
||||
|
||||
if not filename.lower().endswith('.ply'):
|
||||
filename += '.ply'
|
||||
|
||||
if not ob:
|
||||
raise Exception("Error, Select 1 active object")
|
||||
return
|
||||
|
||||
file = open(filename, 'w')
|
||||
|
||||
|
||||
#EXPORT_EDGES = Draw.Create(0)
|
||||
"""
|
||||
is_editmode = Blender.Window.EditMode()
|
||||
if is_editmode:
|
||||
Blender.Window.EditMode(0, '', 0)
|
||||
|
||||
Window.WaitCursor(1)
|
||||
"""
|
||||
if scene.objects.active:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
#mesh = BPyMesh.getMeshFromObject(ob, None, EXPORT_APPLY_MODIFIERS, False, scn) # XXX
|
||||
if EXPORT_APPLY_MODIFIERS:
|
||||
mesh = ob.create_mesh(scene, True, 'PREVIEW')
|
||||
else:
|
||||
mesh = ob.data
|
||||
|
||||
if not mesh:
|
||||
raise ("Error, could not get mesh data from active object")
|
||||
return
|
||||
|
||||
# mesh.transform(ob.matrix_world) # XXX
|
||||
|
||||
faceUV = (len(mesh.uv_textures) > 0)
|
||||
vertexUV = (len(mesh.sticky) > 0)
|
||||
vertexColors = len(mesh.vertex_colors) > 0
|
||||
|
||||
if (not faceUV) and (not vertexUV):
|
||||
EXPORT_UV = False
|
||||
if not vertexColors:
|
||||
EXPORT_COLORS = False
|
||||
|
||||
if not EXPORT_UV:
|
||||
faceUV = vertexUV = False
|
||||
if not EXPORT_COLORS:
|
||||
vertexColors = False
|
||||
|
||||
if faceUV:
|
||||
active_uv_layer = mesh.active_uv_texture
|
||||
if not active_uv_layer:
|
||||
EXPORT_UV = False
|
||||
faceUV = None
|
||||
else:
|
||||
active_uv_layer = active_uv_layer.data
|
||||
|
||||
if vertexColors:
|
||||
active_col_layer = mesh.active_vertex_color
|
||||
if not active_col_layer:
|
||||
EXPORT_COLORS = False
|
||||
vertexColors = None
|
||||
else:
|
||||
active_col_layer = active_col_layer.data
|
||||
|
||||
# incase
|
||||
color = uvcoord = uvcoord_key = normal = normal_key = None
|
||||
|
||||
mesh_verts = mesh.vertices # save a lookup
|
||||
ply_verts = [] # list of dictionaries
|
||||
# vdict = {} # (index, normal, uv) -> new index
|
||||
vdict = [{} for i in range(len(mesh_verts))]
|
||||
ply_faces = [[] for f in range(len(mesh.faces))]
|
||||
vert_count = 0
|
||||
for i, f in enumerate(mesh.faces):
|
||||
|
||||
|
||||
smooth = f.use_smooth
|
||||
if not smooth:
|
||||
normal = tuple(f.normal)
|
||||
normal_key = rvec3d(normal)
|
||||
|
||||
if faceUV:
|
||||
uv = active_uv_layer[i]
|
||||
uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4 # XXX - crufty :/
|
||||
if vertexColors:
|
||||
col = active_col_layer[i]
|
||||
col = col.color1, col.color2, col.color3, col.color4
|
||||
|
||||
f_verts = f.vertices
|
||||
|
||||
pf = ply_faces[i]
|
||||
for j, vidx in enumerate(f_verts):
|
||||
v = mesh_verts[vidx]
|
||||
|
||||
if smooth:
|
||||
normal = tuple(v.normal)
|
||||
normal_key = rvec3d(normal)
|
||||
|
||||
if faceUV:
|
||||
uvcoord = uv[j][0], 1.0 - uv[j][1]
|
||||
uvcoord_key = rvec2d(uvcoord)
|
||||
elif vertexUV:
|
||||
uvcoord = v.uvco[0], 1.0 - v.uvco[1]
|
||||
uvcoord_key = rvec2d(uvcoord)
|
||||
|
||||
if vertexColors:
|
||||
color = col[j]
|
||||
color = int(color[0] * 255.0), int(color[1] * 255.0), int(color[2] * 255.0)
|
||||
|
||||
|
||||
key = normal_key, uvcoord_key, color
|
||||
|
||||
vdict_local = vdict[vidx]
|
||||
pf_vidx = vdict_local.get(key) # Will be None initially
|
||||
|
||||
if pf_vidx == None: # same as vdict_local.has_key(key)
|
||||
pf_vidx = vdict_local[key] = vert_count
|
||||
ply_verts.append((vidx, normal, uvcoord, color))
|
||||
vert_count += 1
|
||||
|
||||
pf.append(pf_vidx)
|
||||
|
||||
file.write('ply\n')
|
||||
file.write('format ascii 1.0\n')
|
||||
file.write('comment Created by Blender %s - www.blender.org, source file: %s\n' % (bpy.app.version_string, bpy.data.filepath.split('/')[-1].split('\\')[-1]))
|
||||
|
||||
file.write('element vertex %d\n' % len(ply_verts))
|
||||
|
||||
file.write('property float x\n')
|
||||
file.write('property float y\n')
|
||||
file.write('property float z\n')
|
||||
|
||||
if EXPORT_NORMALS:
|
||||
file.write('property float nx\n')
|
||||
file.write('property float ny\n')
|
||||
file.write('property float nz\n')
|
||||
if EXPORT_UV:
|
||||
file.write('property float s\n')
|
||||
file.write('property float t\n')
|
||||
if EXPORT_COLORS:
|
||||
file.write('property uchar red\n')
|
||||
file.write('property uchar green\n')
|
||||
file.write('property uchar blue\n')
|
||||
|
||||
file.write('element face %d\n' % len(mesh.faces))
|
||||
file.write('property list uchar uint vertex_indices\n')
|
||||
file.write('end_header\n')
|
||||
|
||||
for i, v in enumerate(ply_verts):
|
||||
file.write('%.6f %.6f %.6f ' % tuple(mesh_verts[v[0]].co)) # co
|
||||
if EXPORT_NORMALS:
|
||||
file.write('%.6f %.6f %.6f ' % v[1]) # no
|
||||
if EXPORT_UV:
|
||||
file.write('%.6f %.6f ' % v[2]) # uv
|
||||
if EXPORT_COLORS:
|
||||
file.write('%u %u %u' % v[3]) # col
|
||||
file.write('\n')
|
||||
|
||||
for pf in ply_faces:
|
||||
if len(pf) == 3:
|
||||
file.write('3 %d %d %d\n' % tuple(pf))
|
||||
else:
|
||||
file.write('4 %d %d %d %d\n' % tuple(pf))
|
||||
|
||||
file.close()
|
||||
print("writing", filename, "done")
|
||||
|
||||
if EXPORT_APPLY_MODIFIERS:
|
||||
bpy.data.meshes.remove(mesh)
|
||||
|
||||
# XXX
|
||||
"""
|
||||
if is_editmode:
|
||||
Blender.Window.EditMode(1, '', 0)
|
||||
"""
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
|
||||
class ExportPLY(bpy.types.Operator):
|
||||
'''Export a single object as a stanford PLY with normals, colours and texture coordinates.'''
|
||||
bl_idname = "export.ply"
|
||||
bl_label = "Export PLY"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
|
||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the PLY file", maxlen=1024, default="")
|
||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
||||
use_modifiers = BoolProperty(name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default=True)
|
||||
use_normals = BoolProperty(name="Normals", description="Export Normals for smooth and hard shaded faces", default=True)
|
||||
use_uvs = BoolProperty(name="UVs", description="Exort the active UV layer", default=True)
|
||||
use_colors = BoolProperty(name="Vertex Colors", description="Exort the active vertex color layer", default=True)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_object != None
|
||||
|
||||
def execute(self, context):
|
||||
filepath = self.properties.filepath
|
||||
filepath = bpy.path.ensure_ext(filepath, ".ply")
|
||||
|
||||
write(filepath, context.scene, context.active_object,\
|
||||
EXPORT_APPLY_MODIFIERS=self.properties.use_modifiers,
|
||||
EXPORT_NORMALS=self.properties.use_normals,
|
||||
EXPORT_UV=self.properties.use_uvs,
|
||||
EXPORT_COLORS=self.properties.use_colors,
|
||||
)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
import os
|
||||
if not self.properties.is_property_set("filepath"):
|
||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".ply"
|
||||
|
||||
context.manager.add_fileselect(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
props = self.properties
|
||||
|
||||
row = layout.row()
|
||||
row.prop(props, "use_modifiers")
|
||||
row.prop(props, "use_normals")
|
||||
row = layout.row()
|
||||
row.prop(props, "use_uvs")
|
||||
row.prop(props, "use_colors")
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(ExportPLY.bl_idname, text="Stanford (.ply)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
@ -1,154 +0,0 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENCE BLOCK *****
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# mdd importer by Bill L.Nieuwendorp
|
||||
# conversion to blender 2.5: Ivo Grigull (loolarge)
|
||||
#
|
||||
# Warning if the vertex order or vertex count differs from the
|
||||
# origonal model the mdd was Baked out from their will be Strange
|
||||
# behavior
|
||||
#
|
||||
# vertex animation to ShapeKeys with ipo and gives the frame a value of 1.0
|
||||
# A modifier to read mdd files would be Ideal but thats for another day :)
|
||||
#
|
||||
# Please send any fixes,updates,bugs to Slow67_at_Gmail.com
|
||||
# Bill Niewuendorp
|
||||
|
||||
import bpy
|
||||
from struct import unpack
|
||||
|
||||
|
||||
def mdd_import(filepath, ob, scene, PREF_START_FRAME=0, PREF_JUMP=1):
|
||||
|
||||
print('\n\nimporting mdd "%s"' % filepath)
|
||||
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
file = open(filepath, 'rb')
|
||||
frames, points = unpack(">2i", file.read(8))
|
||||
time = unpack((">%df" % frames), file.read(frames * 4))
|
||||
|
||||
print('\tpoints:%d frames:%d' % (points, frames))
|
||||
|
||||
# If target object doesn't have Basis shape key, create it.
|
||||
try:
|
||||
num_keys = len(ob.data.shape_keys.keys)
|
||||
except:
|
||||
basis = ob.add_shape_key()
|
||||
basis.name = "Basis"
|
||||
ob.data.update()
|
||||
|
||||
scene.frame_current = PREF_START_FRAME
|
||||
|
||||
def UpdateMesh(ob, fr):
|
||||
|
||||
# Insert new shape key
|
||||
new_shapekey = ob.add_shape_key()
|
||||
new_shapekey.name = ("frame_%.4d" % fr)
|
||||
new_shapekey_name = new_shapekey.name
|
||||
|
||||
ob.active_shape_key_index = len(ob.data.shape_keys.keys)-1
|
||||
index = len(ob.data.shape_keys.keys)-1
|
||||
ob.show_shape_key = True
|
||||
|
||||
verts = ob.data.shape_keys.keys[len(ob.data.shape_keys.keys)-1].data
|
||||
|
||||
|
||||
for v in verts: # 12 is the size of 3 floats
|
||||
v.co[:] = unpack('>3f', file.read(12))
|
||||
#me.update()
|
||||
ob.show_shape_key = False
|
||||
|
||||
|
||||
# insert keyframes
|
||||
shape_keys = ob.data.shape_keys
|
||||
|
||||
scene.frame_current -= 1
|
||||
ob.data.shape_keys.keys[index].value = 0.0
|
||||
shape_keys.keys[len(ob.data.shape_keys.keys)-1].keyframe_insert("value")
|
||||
|
||||
scene.frame_current += 1
|
||||
ob.data.shape_keys.keys[index].value = 1.0
|
||||
shape_keys.keys[len(ob.data.shape_keys.keys)-1].keyframe_insert("value")
|
||||
|
||||
scene.frame_current += 1
|
||||
ob.data.shape_keys.keys[index].value = 0.0
|
||||
shape_keys.keys[len(ob.data.shape_keys.keys)-1].keyframe_insert("value")
|
||||
|
||||
ob.data.update()
|
||||
|
||||
|
||||
for i in range(frames):
|
||||
UpdateMesh(ob, i)
|
||||
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
|
||||
class importMDD(bpy.types.Operator):
|
||||
'''Import MDD vertex keyframe file to shape keys'''
|
||||
bl_idname = "import_shape.mdd"
|
||||
bl_label = "Import MDD"
|
||||
|
||||
# get first scene to get min and max properties for frames, fps
|
||||
|
||||
minframe = 1
|
||||
maxframe = 300000
|
||||
minfps = 1
|
||||
maxfps = 120
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
filepath = StringProperty(name="File Path", description="Filepath used for importing the MDD file", maxlen=1024)
|
||||
#fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default=25)
|
||||
frame_start = IntProperty(name="Start Frame", description="Start frame for inserting animation", min=minframe, max=maxframe, default=0)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.active_object
|
||||
return (ob and ob.type == 'MESH')
|
||||
|
||||
def execute(self, context):
|
||||
if not self.properties.filepath:
|
||||
raise Exception("filename not set")
|
||||
|
||||
mdd_import(self.properties.filepath, bpy.context.active_object, context.scene, self.properties.frame_start, 1)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(importMDD.bl_idname, text="Lightwave Point Cache (.mdd)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_import.append(menu_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_import.remove(menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
@ -19,9 +19,7 @@
|
||||
# This directory is a Python package.
|
||||
|
||||
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||
try:
|
||||
init_data
|
||||
|
||||
if "bpy" in locals():
|
||||
reload(model)
|
||||
reload(operators)
|
||||
reload(client)
|
||||
@ -32,7 +30,7 @@ try:
|
||||
reload(balancing)
|
||||
reload(ui)
|
||||
reload(repath)
|
||||
except:
|
||||
else:
|
||||
from netrender import model
|
||||
from netrender import operators
|
||||
from netrender import client
|
||||
@ -49,7 +47,6 @@ slaves = []
|
||||
blacklist = []
|
||||
|
||||
init_file = ""
|
||||
init_data = True
|
||||
init_address = True
|
||||
|
||||
def register():
|
||||
|
@ -116,7 +116,7 @@ def RKS_GEN_rotation(ksi, context, ks, data):
|
||||
# rotation mode affects the property used
|
||||
if data.rotation_mode == 'QUATERNION':
|
||||
path = path_add_property(base_path, "rotation_quaternion")
|
||||
elif data.rotation_mode == 'AXISANGLE':
|
||||
elif data.rotation_mode == 'AXIS_ANGLE':
|
||||
path = path_add_property(base_path, "rotation_axis_angle")
|
||||
else:
|
||||
path = path_add_property(base_path, "rotation_euler")
|
||||
|
@ -23,6 +23,7 @@ from _bpy import ops as ops_module
|
||||
|
||||
# op_add = ops_module.add
|
||||
op_dir = ops_module.dir
|
||||
op_poll = ops_module.poll
|
||||
op_call = ops_module.call
|
||||
op_as_string = ops_module.as_string
|
||||
op_get_rna = ops_module.get_rna
|
||||
@ -120,6 +121,9 @@ class bpy_ops_submodule_op(object):
|
||||
self.module = module
|
||||
self.func = func
|
||||
|
||||
def poll(self, context=None):
|
||||
return op_poll(self.idname_py(), context)
|
||||
|
||||
def idname(self):
|
||||
# submod.foo -> SUBMOD_OT_foo
|
||||
return self.module.upper() + "_OT_" + self.func
|
||||
|
@ -306,7 +306,9 @@ class Mesh(bpy_types.ID):
|
||||
Make a mesh from a list of verts/edges/faces
|
||||
Until we have a nicer way to make geometry, use this.
|
||||
"""
|
||||
self.add_geometry(len(verts), len(edges), len(faces))
|
||||
self.vertices.add(len(verts))
|
||||
self.edges.add(len(edges))
|
||||
self.faces.add(len(faces))
|
||||
|
||||
verts_flat = [f for v in verts for f in v]
|
||||
self.vertices.foreach_set("co", verts_flat)
|
||||
@ -318,8 +320,11 @@ class Mesh(bpy_types.ID):
|
||||
|
||||
def treat_face(f):
|
||||
if len(f) == 3:
|
||||
return f[0], f[1], f[2], 0
|
||||
elif f[3] == 0:
|
||||
if f[2] == 0:
|
||||
return f[2], f[0], f[1], 0
|
||||
else:
|
||||
return f[0], f[1], f[2], 0
|
||||
elif f[2] == 0 or f[3] == 0:
|
||||
return f[3], f[0], f[1], f[2]
|
||||
return f
|
||||
|
||||
|
@ -262,7 +262,7 @@ def main(obj, bone_definition, base_names, options):
|
||||
fcurve = ex.head_ctrl_p.driver_add('["bend_tot"]')
|
||||
driver = fcurve.driver
|
||||
driver.type = 'SUM'
|
||||
fcurve.modifiers.remove(0) # grr dont need a modifier
|
||||
fcurve.modifiers.remove(fcurve.modifiers[0]) # grr dont need a modifier
|
||||
|
||||
for i in range(len(neck_chain)):
|
||||
var = driver.variables.new()
|
||||
@ -301,7 +301,7 @@ def main(obj, bone_definition, base_names, options):
|
||||
driver.type = 'SCRIPTED'
|
||||
driver.expression = "bend/bend_tot"
|
||||
|
||||
fcurve.modifiers.remove(0) # grr dont need a modifier
|
||||
fcurve.modifiers.remove(fcurve.modifiers[0]) # grr dont need a modifier
|
||||
|
||||
|
||||
# add target
|
||||
|
@ -194,7 +194,7 @@ def main(obj, bone_definition, base_names, options):
|
||||
driver.expression = "(1.0-cos(x))-s"
|
||||
|
||||
for fcurve in driver_fcurves:
|
||||
fcurve.modifiers.remove(0) # grr dont need a modifier
|
||||
fcurve.modifiers.remove(fcurve.modifiers[0]) # grr dont need a modifier
|
||||
|
||||
var = driver.variables.new()
|
||||
var.name = "x"
|
||||
|
@ -353,7 +353,7 @@ def main(obj, bone_definition, base_names, options):
|
||||
fcurve = ex.ribcage_copy_p.driver_add('["bend_tot"]')
|
||||
driver = fcurve.driver
|
||||
driver.type = 'SUM'
|
||||
fcurve.modifiers.remove(0) # grr dont need a modifier
|
||||
fcurve.modifiers.remove(fcurve.modifiers[0]) # grr dont need a modifier
|
||||
|
||||
for i in range(spine_chain_len - 1):
|
||||
var = driver.variables.new()
|
||||
@ -390,7 +390,7 @@ def main(obj, bone_definition, base_names, options):
|
||||
driver.type = 'SCRIPTED'
|
||||
driver.expression = "bend/bend_tot"
|
||||
|
||||
fcurve.modifiers.remove(0) # grr dont need a modifier
|
||||
fcurve.modifiers.remove(fcurve.modifiers[0]) # grr dont need a modifier
|
||||
|
||||
|
||||
# add target
|
||||
|
@ -266,7 +266,7 @@ def main(obj, bone_definition, base_names, options):
|
||||
fcurve = ex.head_ctrl_p.driver_add('["bend_tot"]')
|
||||
driver = fcurve.driver
|
||||
driver.type = 'SUM'
|
||||
fcurve.modifiers.remove(0) # grr dont need a modifier
|
||||
fcurve.modifiers.remove(fcurve.modifiers[0]) # grr dont need a modifier
|
||||
|
||||
for i in range(len(neck_chain)):
|
||||
var = driver.variables.new()
|
||||
@ -313,7 +313,7 @@ def main(obj, bone_definition, base_names, options):
|
||||
driver.type = 'SCRIPTED'
|
||||
driver.expression = "bend/bend_tot"
|
||||
|
||||
fcurve.modifiers.remove(0) # grr dont need a modifier
|
||||
fcurve.modifiers.remove(fcurve.modifiers[0]) # grr dont need a modifier
|
||||
|
||||
|
||||
# add target
|
||||
|
@ -157,7 +157,7 @@ def blend_bone_list(obj, apply_bones, from_bones, to_bones, target_bone=None, ta
|
||||
fcurve = con.driver_add("influence")
|
||||
driver = fcurve.driver
|
||||
driver.type = 'AVERAGE'
|
||||
fcurve.modifiers.remove(0) # grr dont need a modifier
|
||||
fcurve.modifiers.remove(fcurve.modifiers[0]) # grr dont need a modifier
|
||||
|
||||
blend_target(driver)
|
||||
|
||||
|
@ -84,6 +84,8 @@ def draw(layout, context, context_member, use_edit=True):
|
||||
props.data_path = context_member
|
||||
del row
|
||||
|
||||
rna_properties = {prop.identifier for prop in rna_item.bl_rna.properties if prop.is_runtime} if items else None
|
||||
|
||||
for key, val in items:
|
||||
|
||||
if key == '_RNA_UI':
|
||||
@ -113,7 +115,10 @@ def draw(layout, context, context_member, use_edit=True):
|
||||
if convert_to_pyobject and not hasattr(val_orig, "len"):
|
||||
row.label(text=val_draw)
|
||||
else:
|
||||
row.prop(rna_item, '["%s"]' % key, text="")
|
||||
if key in rna_properties:
|
||||
row.prop(rna_item, key, text="")
|
||||
else:
|
||||
row.prop(rna_item, '["%s"]' % key, text="")
|
||||
|
||||
if use_edit:
|
||||
row = split.row(align=True)
|
||||
@ -130,11 +135,11 @@ class PropertyPanel():
|
||||
and the variable '_context_path' MUST be set.
|
||||
"""
|
||||
bl_label = "Custom Properties"
|
||||
bl_default_closed = True
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
bool(eval("context.%s" % cls._context_path))
|
||||
return bool(eval("context.%s" % cls._context_path))
|
||||
|
||||
def draw(self, context):
|
||||
draw(self.layout, context, self._context_path)
|
||||
|
@ -121,7 +121,9 @@ class AddTorus(bpy.types.Operator):
|
||||
|
||||
mesh = bpy.data.meshes.new("Torus")
|
||||
|
||||
mesh.add_geometry(int(len(verts_loc) / 3), 0, int(len(faces) / 4))
|
||||
mesh.vertices.add(len(verts_loc) // 3)
|
||||
mesh.faces.add(len(faces) // 4)
|
||||
|
||||
mesh.vertices.foreach_set("co", verts_loc)
|
||||
mesh.faces.foreach_set("vertices_raw", faces)
|
||||
mesh.update()
|
||||
@ -133,7 +135,7 @@ class AddTorus(bpy.types.Operator):
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(AddTorus.bl_idname, text="Torus", icon='MESH_DONUT')
|
||||
self.layout.operator(AddTorus.bl_idname, text="Torus", icon='MESH_TORUS')
|
||||
|
||||
|
||||
def register():
|
||||
|
4
release/scripts/op/animsys_update.py
Executable file → Normal file
4
release/scripts/op/animsys_update.py
Executable file → Normal file
@ -681,7 +681,7 @@ import bpy
|
||||
|
||||
|
||||
class UpdateAnimData(bpy.types.Operator):
|
||||
''''''
|
||||
'''Update data paths from 2.53 to edited data paths of drivers and fcurves'''
|
||||
bl_idname = "anim.update_data_paths"
|
||||
bl_label = "Update Animation Data"
|
||||
|
||||
@ -696,4 +696,4 @@ if __name__ == "__main__":
|
||||
bpy.ops.anim.update_data_paths()
|
||||
|
||||
def register():
|
||||
pass
|
||||
pass
|
||||
|
74
release/scripts/op/io_anim_bvh/__init__.py
Normal file
74
release/scripts/op/io_anim_bvh/__init__.py
Normal file
@ -0,0 +1,74 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||
if "bpy" in locals():
|
||||
# only reload if we alredy loaded, highly annoying
|
||||
import sys
|
||||
reload(sys.modules.get("io_mesh_ply.export_ply", sys))
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy.props import *
|
||||
from io_utils import ImportHelper
|
||||
|
||||
|
||||
class BvhImporter(bpy.types.Operator, ImportHelper):
|
||||
'''Load a OBJ Motion Capture File'''
|
||||
bl_idname = "import_anim.bvh"
|
||||
bl_label = "Import BVH"
|
||||
|
||||
filename_ext = ".bvh"
|
||||
|
||||
scale = FloatProperty(name="Scale", description="Scale the BVH by this value", min=0.0001, max=1000000.0, soft_min=0.001, soft_max=100.0, default=0.1)
|
||||
frame_start = IntProperty(name="Start Frame", description="Starting frame for the animation", default=1)
|
||||
loop = BoolProperty(name="Loop", description="Loop the animation playback", default=False)
|
||||
rotate_mode = EnumProperty(items=(
|
||||
('QUATERNION', "Quaternion", "Convert rotations to quaternions"),
|
||||
('NATIVE', "Euler (Native)", "Use the rotation order defined in the BVH file"),
|
||||
('XYZ', "Euler (XYZ)", "Convert rotations to euler XYZ"),
|
||||
('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
|
||||
('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
|
||||
('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
|
||||
('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
|
||||
('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX"),
|
||||
),
|
||||
name="Rotation",
|
||||
description="Rotation conversion.",
|
||||
default='NATIVE')
|
||||
|
||||
def execute(self, context):
|
||||
import io_anim_bvh.import_bvh
|
||||
return io_anim_bvh.import_bvh.load(self, context, **self.properties)
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(BvhImporter.bl_idname, text="Motion Capture (.bvh)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_import.append(menu_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_import.remove(menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
@ -18,6 +18,8 @@
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# Script copyright (C) Campbell Barton
|
||||
|
||||
import math
|
||||
from math import radians
|
||||
|
||||
@ -349,7 +351,7 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
|
||||
for ob in scn.objects:
|
||||
ob.select = False
|
||||
|
||||
scn.set_frame(IMPORT_START_FRAME)
|
||||
scn.frame_set(IMPORT_START_FRAME)
|
||||
|
||||
arm_data = bpy.data.armatures.new("MyBVH")
|
||||
arm_ob = bpy.data.objects.new("MyBVH", arm_data)
|
||||
@ -553,70 +555,24 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
|
||||
return arm_ob
|
||||
|
||||
|
||||
from bpy.props import *
|
||||
def load(operator, context, filepath="", rotate_mode='NATIVE', scale=1.0, use_cyclic=False, frame_start=1):
|
||||
import time
|
||||
t1 = time.time()
|
||||
print('\tparsing bvh %r...' % filepath, end="")
|
||||
|
||||
bvh_nodes = read_bvh(context, filepath,
|
||||
ROT_MODE=rotate_mode,
|
||||
GLOBAL_SCALE=scale)
|
||||
|
||||
class BvhImporter(bpy.types.Operator):
|
||||
'''Load a OBJ Motion Capture File'''
|
||||
bl_idname = "import_anim.bvh"
|
||||
bl_label = "Import BVH"
|
||||
print('%.4f' % (time.time() - t1))
|
||||
t1 = time.time()
|
||||
print('\timporting to blender...', end="")
|
||||
|
||||
filepath = StringProperty(name="File Path", description="Filepath used for importing the OBJ file", maxlen=1024, default="")
|
||||
scale = FloatProperty(name="Scale", description="Scale the BVH by this value", min=0.0001, max=1000000.0, soft_min=0.001, soft_max=100.0, default=0.1)
|
||||
frame_start = IntProperty(name="Start Frame", description="Starting frame for the animation", default=1)
|
||||
loop = BoolProperty(name="Loop", description="Loop the animation playback", default=False)
|
||||
rotate_mode = EnumProperty(items=(
|
||||
('QUATERNION', "Quaternion", "Convert rotations to quaternions"),
|
||||
('NATIVE', "Euler (Native)", "Use the rotation order defined in the BVH file"),
|
||||
('XYZ', "Euler (XYZ)", "Convert rotations to euler XYZ"),
|
||||
('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
|
||||
('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
|
||||
('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
|
||||
('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
|
||||
('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX"),
|
||||
),
|
||||
name="Rotation",
|
||||
description="Rotation conversion.",
|
||||
default='NATIVE')
|
||||
bvh_node_dict2armature(context, bvh_nodes,
|
||||
ROT_MODE=rotate_mode,
|
||||
IMPORT_START_FRAME=frame_start,
|
||||
IMPORT_LOOP=use_cyclic)
|
||||
|
||||
def execute(self, context):
|
||||
# print("Selected: " + context.active_object.name)
|
||||
import time
|
||||
t1 = time.time()
|
||||
print('\tparsing bvh...', end="")
|
||||
|
||||
bvh_nodes = read_bvh(context, self.properties.filepath,
|
||||
ROT_MODE=self.properties.rotate_mode,
|
||||
GLOBAL_SCALE=self.properties.scale)
|
||||
|
||||
print('%.4f' % (time.time() - t1))
|
||||
t1 = time.time()
|
||||
print('\timporting to blender...', end="")
|
||||
|
||||
bvh_node_dict2armature(context, bvh_nodes,
|
||||
ROT_MODE=self.properties.rotate_mode,
|
||||
IMPORT_START_FRAME=self.properties.frame_start,
|
||||
IMPORT_LOOP=self.properties.loop)
|
||||
|
||||
print('Done in %.4f\n' % (time.time() - t1))
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(BvhImporter.bl_idname, text="Motion Capture (.bvh)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_import.append(menu_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_import.remove(menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
print('Done in %.4f\n' % (time.time() - t1))
|
||||
|
||||
return {'FINISHED'}
|
76
release/scripts/op/io_mesh_ply/__init__.py
Normal file
76
release/scripts/op/io_mesh_ply/__init__.py
Normal file
@ -0,0 +1,76 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||
if "bpy" in locals():
|
||||
import sys
|
||||
reload(sys.modules.get("io_mesh_ply.export_ply", sys))
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy.props import *
|
||||
from io_utils import ExportHelper
|
||||
|
||||
|
||||
class ExportPLY(bpy.types.Operator, ExportHelper):
|
||||
'''Export a single object as a stanford PLY with normals, colours and texture coordinates.'''
|
||||
bl_idname = "export.ply"
|
||||
bl_label = "Export PLY"
|
||||
|
||||
filename_ext = ".ply"
|
||||
|
||||
use_modifiers = BoolProperty(name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default=True)
|
||||
use_normals = BoolProperty(name="Normals", description="Export Normals for smooth and hard shaded faces", default=True)
|
||||
use_uv_coords = BoolProperty(name="UVs", description="Exort the active UV layer", default=True)
|
||||
use_colors = BoolProperty(name="Vertex Colors", description="Exort the active vertex color layer", default=True)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_object != None
|
||||
|
||||
def execute(self, context):
|
||||
filepath = self.properties.filepath
|
||||
filepath = bpy.path.ensure_ext(filepath, self.filename_ext)
|
||||
import io_mesh_ply.export_ply
|
||||
return io_mesh_ply.export_ply.save(self, context, **self.properties)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
props = self.properties
|
||||
|
||||
row = layout.row()
|
||||
row.prop(props, "use_modifiers")
|
||||
row.prop(props, "use_normals")
|
||||
row = layout.row()
|
||||
row.prop(props, "use_uv_coords")
|
||||
row.prop(props, "use_colors")
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(ExportPLY.bl_idname, text="Stanford (.ply)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
206
release/scripts/op/io_mesh_ply/export_ply.py
Normal file
206
release/scripts/op/io_mesh_ply/export_ply.py
Normal file
@ -0,0 +1,206 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
|
||||
# Contributors: Bruce Merry, Campbell Barton
|
||||
|
||||
"""
|
||||
This script exports Stanford PLY files from Blender. It supports normals,
|
||||
colours, and texture coordinates per face or per vertex.
|
||||
Only one mesh can be exported at a time.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
import os
|
||||
|
||||
|
||||
def save(operator, context, filepath="", use_modifiers=True, use_normals=True, use_uv_coords=True, use_colors=True):
|
||||
|
||||
def rvec3d(v):
|
||||
return round(v[0], 6), round(v[1], 6), round(v[2], 6)
|
||||
|
||||
|
||||
def rvec2d(v):
|
||||
return round(v[0], 6), round(v[1], 6)
|
||||
|
||||
scene = context.scene
|
||||
obj = context.object
|
||||
|
||||
if not obj:
|
||||
raise Exception("Error, Select 1 active object")
|
||||
|
||||
file = open(filepath, 'w')
|
||||
|
||||
if scene.objects.active:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
if use_modifiers:
|
||||
mesh = obj.create_mesh(scene, True, 'PREVIEW')
|
||||
else:
|
||||
mesh = obj.data
|
||||
|
||||
if not mesh:
|
||||
raise Exception("Error, could not get mesh data from active object")
|
||||
|
||||
# mesh.transform(obj.matrix_world) # XXX
|
||||
|
||||
faceUV = (len(mesh.uv_textures) > 0)
|
||||
vertexUV = (len(mesh.sticky) > 0)
|
||||
vertexColors = len(mesh.vertex_colors) > 0
|
||||
|
||||
if (not faceUV) and (not vertexUV):
|
||||
use_uv_coords = False
|
||||
if not vertexColors:
|
||||
use_colors = False
|
||||
|
||||
if not use_uv_coords:
|
||||
faceUV = vertexUV = False
|
||||
if not use_colors:
|
||||
vertexColors = False
|
||||
|
||||
if faceUV:
|
||||
active_uv_layer = mesh.uv_textures.active
|
||||
if not active_uv_layer:
|
||||
use_uv_coords = False
|
||||
faceUV = None
|
||||
else:
|
||||
active_uv_layer = active_uv_layer.data
|
||||
|
||||
if vertexColors:
|
||||
active_col_layer = mesh.vertex_colors.active
|
||||
if not active_col_layer:
|
||||
use_colors = False
|
||||
vertexColors = None
|
||||
else:
|
||||
active_col_layer = active_col_layer.data
|
||||
|
||||
# incase
|
||||
color = uvcoord = uvcoord_key = normal = normal_key = None
|
||||
|
||||
mesh_verts = mesh.vertices # save a lookup
|
||||
ply_verts = [] # list of dictionaries
|
||||
# vdict = {} # (index, normal, uv) -> new index
|
||||
vdict = [{} for i in range(len(mesh_verts))]
|
||||
ply_faces = [[] for f in range(len(mesh.faces))]
|
||||
vert_count = 0
|
||||
for i, f in enumerate(mesh.faces):
|
||||
|
||||
|
||||
smooth = f.use_smooth
|
||||
if not smooth:
|
||||
normal = tuple(f.normal)
|
||||
normal_key = rvec3d(normal)
|
||||
|
||||
if faceUV:
|
||||
uv = active_uv_layer[i]
|
||||
uv = uv.uv1, uv.uv2, uv.uv3, uv.uv4 # XXX - crufty :/
|
||||
if vertexColors:
|
||||
col = active_col_layer[i]
|
||||
col = col.color1, col.color2, col.color3, col.color4
|
||||
|
||||
f_verts = f.vertices
|
||||
|
||||
pf = ply_faces[i]
|
||||
for j, vidx in enumerate(f_verts):
|
||||
v = mesh_verts[vidx]
|
||||
|
||||
if smooth:
|
||||
normal = tuple(v.normal)
|
||||
normal_key = rvec3d(normal)
|
||||
|
||||
if faceUV:
|
||||
uvcoord = uv[j][0], 1.0 - uv[j][1]
|
||||
uvcoord_key = rvec2d(uvcoord)
|
||||
elif vertexUV:
|
||||
uvcoord = v.uvco[0], 1.0 - v.uvco[1]
|
||||
uvcoord_key = rvec2d(uvcoord)
|
||||
|
||||
if vertexColors:
|
||||
color = col[j]
|
||||
color = int(color[0] * 255.0), int(color[1] * 255.0), int(color[2] * 255.0)
|
||||
|
||||
|
||||
key = normal_key, uvcoord_key, color
|
||||
|
||||
vdict_local = vdict[vidx]
|
||||
pf_vidx = vdict_local.get(key) # Will be None initially
|
||||
|
||||
if pf_vidx == None: # same as vdict_local.has_key(key)
|
||||
pf_vidx = vdict_local[key] = vert_count
|
||||
ply_verts.append((vidx, normal, uvcoord, color))
|
||||
vert_count += 1
|
||||
|
||||
pf.append(pf_vidx)
|
||||
|
||||
file.write('ply\n')
|
||||
file.write('format ascii 1.0\n')
|
||||
file.write('comment Created by Blender %s - www.blender.org, source file: %r\n' % (bpy.app.version_string, os.path.basename(bpy.data.filepath)))
|
||||
|
||||
file.write('element vertex %d\n' % len(ply_verts))
|
||||
|
||||
file.write('property float x\n')
|
||||
file.write('property float y\n')
|
||||
file.write('property float z\n')
|
||||
|
||||
if use_normals:
|
||||
file.write('property float nx\n')
|
||||
file.write('property float ny\n')
|
||||
file.write('property float nz\n')
|
||||
if use_uv_coords:
|
||||
file.write('property float s\n')
|
||||
file.write('property float t\n')
|
||||
if use_colors:
|
||||
file.write('property uchar red\n')
|
||||
file.write('property uchar green\n')
|
||||
file.write('property uchar blue\n')
|
||||
|
||||
file.write('element face %d\n' % len(mesh.faces))
|
||||
file.write('property list uchar uint vertex_indices\n')
|
||||
file.write('end_header\n')
|
||||
|
||||
for i, v in enumerate(ply_verts):
|
||||
file.write('%.6f %.6f %.6f ' % tuple(mesh_verts[v[0]].co)) # co
|
||||
if use_normals:
|
||||
file.write('%.6f %.6f %.6f ' % v[1]) # no
|
||||
if use_uv_coords:
|
||||
file.write('%.6f %.6f ' % v[2]) # uv
|
||||
if use_colors:
|
||||
file.write('%u %u %u' % v[3]) # col
|
||||
file.write('\n')
|
||||
|
||||
for pf in ply_faces:
|
||||
if len(pf) == 3:
|
||||
file.write('3 %d %d %d\n' % tuple(pf))
|
||||
else:
|
||||
file.write('4 %d %d %d %d\n' % tuple(pf))
|
||||
|
||||
file.close()
|
||||
print("writing %r done" % filepath)
|
||||
|
||||
if use_modifiers:
|
||||
bpy.data.meshes.remove(mesh)
|
||||
|
||||
# XXX
|
||||
"""
|
||||
if is_editmode:
|
||||
Blender.Window.EditMode(1, '', 0)
|
||||
"""
|
||||
|
||||
return {'FINISHED'}
|
86
release/scripts/op/io_scene_3ds/__init__.py
Normal file
86
release/scripts/op/io_scene_3ds/__init__.py
Normal file
@ -0,0 +1,86 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||
if "bpy" in locals():
|
||||
import sys
|
||||
reload(sys.modules.get("io_scene_3ds.import_3ds", sys))
|
||||
reload(sys.modules.get("io_scene_3ds.export_3ds", sys))
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy.props import *
|
||||
from io_utils import ImportHelper, ExportHelper
|
||||
|
||||
|
||||
class Import3DS(bpy.types.Operator, ImportHelper):
|
||||
'''Import from 3DS file format (.3ds)'''
|
||||
bl_idname = "import_scene.autodesk_3ds"
|
||||
bl_label = 'Import 3DS'
|
||||
|
||||
filename_ext = ".3ds"
|
||||
|
||||
constrain_size = FloatProperty(name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0)
|
||||
use_image_search = BoolProperty(name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True)
|
||||
use_apply_transform = BoolProperty(name="Apply Transform", description="Workaround for object transformations importing incorrectly", default=False)
|
||||
|
||||
def execute(self, context):
|
||||
import io_scene_3ds.import_3ds
|
||||
return io_scene_3ds.import_3ds.load(self, context, **self.properties)
|
||||
|
||||
|
||||
class Export3DS(bpy.types.Operator, ExportHelper):
|
||||
'''Export to 3DS file format (.3ds)'''
|
||||
bl_idname = "export_scene.autodesk_3ds"
|
||||
bl_label = 'Export 3DS'
|
||||
|
||||
filename_ext = ".3ds"
|
||||
|
||||
def execute(self, context):
|
||||
import io_scene_3ds.export_3ds
|
||||
return io_scene_3ds.export_3ds.save(self, context, **self.properties)
|
||||
|
||||
|
||||
# Add to a menu
|
||||
def menu_func_export(self, context):
|
||||
self.layout.operator(Export3DS.bl_idname, text="3D Studio (.3ds)")
|
||||
|
||||
def menu_func_import(self, context):
|
||||
self.layout.operator(Import3DS.bl_idname, text="3D Studio (.3ds)")
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_import.append(menu_func_import)
|
||||
bpy.types.INFO_MT_file_export.append(menu_func_export)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_import.remove(menu_func_import)
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func_export)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# NOTES:
|
||||
# why add 1 extra vertex? and remove it when done? - "Answer - eekadoodle - would need to re-order UV's without this since face order isnt always what we give blender, BMesh will solve :D"
|
||||
# disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
@ -1,4 +1,3 @@
|
||||
# coding: utf-8
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
@ -19,74 +18,74 @@
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
__author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"]
|
||||
__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/")
|
||||
__version__ = "0.90a"
|
||||
__bpydoc__ = """\
|
||||
|
||||
3ds Exporter
|
||||
|
||||
This script Exports a 3ds file.
|
||||
# Script copyright (C) Bob Holcomb
|
||||
# Contributors: Campbell Barton, Bob Holcomb, Richard Lärkäng, Damien McGinnes, Mark Stijnman
|
||||
|
||||
"""
|
||||
Exporting is based on 3ds loader from www.gametutorials.com(Thanks DigiBen) and using information
|
||||
from the lib3ds project (http://lib3ds.sourceforge.net/) sourcecode.
|
||||
"""
|
||||
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# Script copyright (C) Bob Holcomb
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENCE BLOCK *****
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
|
||||
######################################################
|
||||
# Importing modules
|
||||
# Data Structures
|
||||
######################################################
|
||||
|
||||
#Some of the chunks that we will export
|
||||
#----- Primary Chunk, at the beginning of each file
|
||||
PRIMARY= 0x4D4D
|
||||
|
||||
#------ Main Chunks
|
||||
OBJECTINFO = 0x3D3D #This gives the version of the mesh and is found right before the material and object information
|
||||
VERSION = 0x0002 #This gives the version of the .3ds file
|
||||
KFDATA = 0xB000 #This is the header for all of the key frame info
|
||||
|
||||
#------ sub defines of OBJECTINFO
|
||||
MATERIAL=45055 #0xAFFF // This stored the texture info
|
||||
OBJECT=16384 #0x4000 // This stores the faces, vertices, etc...
|
||||
|
||||
#>------ sub defines of MATERIAL
|
||||
MATNAME = 0xA000 # This holds the material name
|
||||
MATAMBIENT = 0xA010 # Ambient color of the object/material
|
||||
MATDIFFUSE = 0xA020 # This holds the color of the object/material
|
||||
MATSPECULAR = 0xA030 # SPecular color of the object/material
|
||||
MATSHINESS = 0xA040 # ??
|
||||
MATMAP = 0xA200 # This is a header for a new material
|
||||
MATMAPFILE = 0xA300 # This holds the file name of the texture
|
||||
|
||||
RGB1= 0x0011
|
||||
RGB2= 0x0012
|
||||
|
||||
#>------ sub defines of OBJECT
|
||||
OBJECT_MESH = 0x4100 # This lets us know that we are reading a new object
|
||||
OBJECT_LIGHT = 0x4600 # This lets un know we are reading a light object
|
||||
OBJECT_CAMERA= 0x4700 # This lets un know we are reading a camera object
|
||||
|
||||
#>------ sub defines of CAMERA
|
||||
OBJECT_CAM_RANGES= 0x4720 # The camera range values
|
||||
|
||||
#>------ sub defines of OBJECT_MESH
|
||||
OBJECT_VERTICES = 0x4110 # The objects vertices
|
||||
OBJECT_FACES = 0x4120 # The objects faces
|
||||
OBJECT_MATERIAL = 0x4130 # This is found if the object has a material, either texture map or color
|
||||
OBJECT_UV = 0x4140 # The UV texture coordinates
|
||||
OBJECT_TRANS_MATRIX = 0x4160 # The Object Matrix
|
||||
|
||||
#>------ sub defines of KFDATA
|
||||
KFDATA_KFHDR = 0xB00A
|
||||
KFDATA_KFSEG = 0xB008
|
||||
KFDATA_KFCURTIME = 0xB009
|
||||
KFDATA_OBJECT_NODE_TAG = 0xB002
|
||||
|
||||
#>------ sub defines of OBJECT_NODE_TAG
|
||||
OBJECT_NODE_ID = 0xB030
|
||||
OBJECT_NODE_HDR = 0xB010
|
||||
OBJECT_PIVOT = 0xB013
|
||||
OBJECT_INSTANCE_NAME = 0xB011
|
||||
POS_TRACK_TAG = 0xB020
|
||||
ROT_TRACK_TAG = 0xB021
|
||||
SCL_TRACK_TAG = 0xB022
|
||||
|
||||
import struct
|
||||
import os
|
||||
import time
|
||||
|
||||
import bpy
|
||||
|
||||
# import Blender
|
||||
# from BPyMesh import getMeshFromObject
|
||||
# from BPyObject import getDerivedObjects
|
||||
# try:
|
||||
# import struct
|
||||
# except:
|
||||
# struct = None
|
||||
|
||||
# also used by X3D exporter
|
||||
# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects()
|
||||
def create_derived_objects(scene, ob):
|
||||
if ob.parent and ob.parent.dupli_type != 'NONE':
|
||||
return False, None
|
||||
|
||||
if ob.dupli_type != 'NONE':
|
||||
ob.create_dupli_list(scene)
|
||||
return True, [(dob.object, dob.matrix) for dob in ob.dupli_list]
|
||||
else:
|
||||
return False, [(ob, ob.matrix_world)]
|
||||
|
||||
# also used by X3D exporter
|
||||
def free_derived_objects(ob):
|
||||
ob.free_dupli_list()
|
||||
|
||||
# So 3ds max can open files, limit names to 12 in length
|
||||
# this is verry annoying for filenames!
|
||||
@ -94,13 +93,10 @@ name_unique = []
|
||||
name_mapping = {}
|
||||
def sane_name(name):
|
||||
name_fixed = name_mapping.get(name)
|
||||
if name_fixed != None:
|
||||
if name_fixed is not None:
|
||||
return name_fixed
|
||||
|
||||
if len(name) > 12:
|
||||
new_name = name[:12]
|
||||
else:
|
||||
new_name = name
|
||||
new_name = name[:12]
|
||||
|
||||
i = 0
|
||||
|
||||
@ -112,65 +108,6 @@ def sane_name(name):
|
||||
name_mapping[name] = new_name
|
||||
return new_name
|
||||
|
||||
######################################################
|
||||
# Data Structures
|
||||
######################################################
|
||||
|
||||
#Some of the chunks that we will export
|
||||
#----- Primary Chunk, at the beginning of each file
|
||||
PRIMARY= int("0x4D4D",16)
|
||||
|
||||
#------ Main Chunks
|
||||
OBJECTINFO = int("0x3D3D",16); #This gives the version of the mesh and is found right before the material and object information
|
||||
VERSION = int("0x0002",16); #This gives the version of the .3ds file
|
||||
KFDATA = int("0xB000",16); #This is the header for all of the key frame info
|
||||
|
||||
#------ sub defines of OBJECTINFO
|
||||
MATERIAL=45055 #0xAFFF // This stored the texture info
|
||||
OBJECT=16384 #0x4000 // This stores the faces, vertices, etc...
|
||||
|
||||
#>------ sub defines of MATERIAL
|
||||
MATNAME = int("0xA000",16); # This holds the material name
|
||||
MATAMBIENT = int("0xA010",16); # Ambient color of the object/material
|
||||
MATDIFFUSE = int("0xA020",16); # This holds the color of the object/material
|
||||
MATSPECULAR = int("0xA030",16); # SPecular color of the object/material
|
||||
MATSHINESS = int("0xA040",16); # ??
|
||||
MATMAP = int("0xA200",16); # This is a header for a new material
|
||||
MATMAPFILE = int("0xA300",16); # This holds the file name of the texture
|
||||
|
||||
RGB1= int("0x0011",16)
|
||||
RGB2= int("0x0012",16)
|
||||
|
||||
#>------ sub defines of OBJECT
|
||||
OBJECT_MESH = int("0x4100",16); # This lets us know that we are reading a new object
|
||||
OBJECT_LIGHT = int("0x4600",16); # This lets un know we are reading a light object
|
||||
OBJECT_CAMERA= int("0x4700",16); # This lets un know we are reading a camera object
|
||||
|
||||
#>------ sub defines of CAMERA
|
||||
OBJECT_CAM_RANGES= int("0x4720",16); # The camera range values
|
||||
|
||||
#>------ sub defines of OBJECT_MESH
|
||||
OBJECT_VERTICES = int("0x4110",16); # The objects vertices
|
||||
OBJECT_FACES = int("0x4120",16); # The objects faces
|
||||
OBJECT_MATERIAL = int("0x4130",16); # This is found if the object has a material, either texture map or color
|
||||
OBJECT_UV = int("0x4140",16); # The UV texture coordinates
|
||||
OBJECT_TRANS_MATRIX = int("0x4160",16); # The Object Matrix
|
||||
|
||||
#>------ sub defines of KFDATA
|
||||
KFDATA_KFHDR = int("0xB00A",16);
|
||||
KFDATA_KFSEG = int("0xB008",16);
|
||||
KFDATA_KFCURTIME = int("0xB009",16);
|
||||
KFDATA_OBJECT_NODE_TAG = int("0xB002",16);
|
||||
|
||||
#>------ sub defines of OBJECT_NODE_TAG
|
||||
OBJECT_NODE_ID = int("0xB030",16);
|
||||
OBJECT_NODE_HDR = int("0xB010",16);
|
||||
OBJECT_PIVOT = int("0xB013",16);
|
||||
OBJECT_INSTANCE_NAME = int("0xB011",16);
|
||||
POS_TRACK_TAG = int("0xB020",16);
|
||||
ROT_TRACK_TAG = int("0xB021",16);
|
||||
SCL_TRACK_TAG = int("0xB022",16);
|
||||
|
||||
def uv_key(uv):
|
||||
return round(uv[0], 6), round(uv[1], 6)
|
||||
# return round(uv.x, 6), round(uv.y, 6)
|
||||
@ -379,7 +316,7 @@ class _3ds_named_variable(object):
|
||||
if (self.value!=None):
|
||||
spaces=""
|
||||
for i in range(indent):
|
||||
spaces+=" ";
|
||||
spaces += " "
|
||||
if (self.name!=""):
|
||||
print(spaces, self.name, " = ", self.value)
|
||||
else:
|
||||
@ -444,7 +381,7 @@ class _3ds_chunk(object):
|
||||
Uses the dump function of the named variables and the subchunks to do the actual work.'''
|
||||
spaces=""
|
||||
for i in range(indent):
|
||||
spaces+=" ";
|
||||
spaces += " "
|
||||
print(spaces, "ID=", hex(self.ID.value), "size=", self.get_size())
|
||||
for variable in self.variables:
|
||||
variable.dump(indent+1)
|
||||
@ -479,11 +416,11 @@ def make_material_subchunk(id, color):
|
||||
Used for color subchunks, such as diffuse color or ambient color subchunks.'''
|
||||
mat_sub = _3ds_chunk(id)
|
||||
col1 = _3ds_chunk(RGB1)
|
||||
col1.add_variable("color1", _3ds_rgb_color(color));
|
||||
col1.add_variable("color1", _3ds_rgb_color(color))
|
||||
mat_sub.add_subchunk(col1)
|
||||
# optional:
|
||||
# col2 = _3ds_chunk(RGB1)
|
||||
# col2.add_variable("color2", _3ds_rgb_color(color));
|
||||
# col2.add_variable("color2", _3ds_rgb_color(color))
|
||||
# mat_sub.add_subchunk(col2)
|
||||
return mat_sub
|
||||
|
||||
@ -567,7 +504,7 @@ def extract_triangles(mesh):
|
||||
f_v = face.vertices
|
||||
# f_v = face.v
|
||||
|
||||
uf = mesh.active_uv_texture.data[i] if do_uv else None
|
||||
uf = mesh.uv_textures.active.data[i] if do_uv else None
|
||||
|
||||
if do_uv:
|
||||
f_uv = uf.uv
|
||||
@ -921,27 +858,21 @@ def make_kf_obj_node(obj, name_to_id):
|
||||
return kf_obj_node
|
||||
"""
|
||||
|
||||
# import BPyMessages
|
||||
def write(filename, context):
|
||||
|
||||
def save(operator, context, filepath=""):
|
||||
import bpy
|
||||
import time
|
||||
from io_utils import create_derived_objects, free_derived_objects
|
||||
|
||||
'''Save the Blender scene to a 3ds file.'''
|
||||
|
||||
# Time the export
|
||||
|
||||
if not filename.lower().endswith('.3ds'):
|
||||
filename += '.3ds'
|
||||
|
||||
# XXX
|
||||
# if not BPyMessages.Warning_SaveOver(filename):
|
||||
# return
|
||||
|
||||
# XXX
|
||||
time1 = time.clock()
|
||||
# time1= Blender.sys.time()
|
||||
# Blender.Window.WaitCursor(1)
|
||||
|
||||
sce = context.scene
|
||||
# sce= bpy.data.scenes.active
|
||||
|
||||
if context.object:
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
# Initialize the main chunk (primary):
|
||||
@ -998,7 +929,7 @@ def write(filename, context):
|
||||
if not mat_ls:
|
||||
mat = mat_name = None
|
||||
|
||||
for f, uf in zip(data.faces, data.active_uv_texture.data):
|
||||
for f, uf in zip(data.faces, data.uv_textures.active.data):
|
||||
if mat_ls:
|
||||
mat_index = f.material_index
|
||||
# mat_index = f.mat
|
||||
@ -1090,7 +1021,7 @@ def write(filename, context):
|
||||
# Check the size:
|
||||
primary.get_size()
|
||||
# Open the file for writing:
|
||||
file = open( filename, 'wb' )
|
||||
file = open(filepath, 'wb')
|
||||
|
||||
# Recursively write the chunks to file:
|
||||
primary.write(file)
|
||||
@ -1098,56 +1029,15 @@ def write(filename, context):
|
||||
# Close the file:
|
||||
file.close()
|
||||
|
||||
# Clear name mapping vars, could make locals too
|
||||
name_unique[:] = []
|
||||
name_mapping.clear()
|
||||
|
||||
# Debugging only: report the exporting time:
|
||||
# Blender.Window.WaitCursor(0)
|
||||
print("3ds export time: %.2f" % (time.clock() - time1))
|
||||
# print("3ds export time: %.2f" % (Blender.sys.time() - time1))
|
||||
|
||||
# Debugging only: dump the chunk hierarchy:
|
||||
#primary.dump()
|
||||
|
||||
|
||||
# # write('/test_b.3ds')
|
||||
from bpy.props import *
|
||||
class Export3DS(bpy.types.Operator):
|
||||
'''Export to 3DS file format (.3ds)'''
|
||||
bl_idname = "export.autodesk_3ds"
|
||||
bl_label = 'Export 3DS'
|
||||
|
||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the 3DS file", maxlen= 1024, default= "")
|
||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context): # Poll isnt working yet
|
||||
return context.active_object != None
|
||||
|
||||
def execute(self, context):
|
||||
filepath = self.properties.filepath
|
||||
filepath = bpy.path.ensure_ext(filepath, ".3ds")
|
||||
|
||||
write(filepath, context)
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
import os
|
||||
if not self.properties.is_property_set("filepath"):
|
||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".3ds"
|
||||
|
||||
context.manager.add_fileselect(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
# Add to a menu
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(Export3DS.bl_idname, text="3D Studio (.3ds)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
return {'FINISHED'}
|
@ -18,130 +18,14 @@
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
__author__= ['Bob Holcomb', 'Richard L?rk?ng', 'Damien McGinnes', 'Campbell Barton', 'Mario Lapin']
|
||||
__url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/")
|
||||
__version__= '0.996'
|
||||
__bpydoc__= '''\
|
||||
|
||||
3ds Importer
|
||||
|
||||
This script imports a 3ds file and the materials into Blender for editing.
|
||||
|
||||
Loader is based on 3ds loader from www.gametutorials.com (Thanks DigiBen).
|
||||
|
||||
0.996 by Mario Lapin (mario.lapin@gmail.com) 13/04/200 <br>
|
||||
- Implemented workaround to correct association between name, geometry and materials of
|
||||
imported meshes.
|
||||
|
||||
Without this patch, version 0.995 of this importer would associate to each mesh object the
|
||||
geometry and the materials of the previously parsed mesh object. By so, the name of the
|
||||
first mesh object would be thrown away, and the name of the last mesh object would be
|
||||
automatically merged with a '.001' at the end. No object would desappear, however object's
|
||||
names and materials would be completely jumbled.
|
||||
|
||||
0.995 by Campbell Barton<br>
|
||||
- workaround for buggy mesh vert delete
|
||||
- minor tweaks
|
||||
|
||||
0.99 by Bob Holcomb<br>
|
||||
- added support for floating point color values that previously broke on import.
|
||||
|
||||
0.98 by Campbell Barton<br>
|
||||
- import faces and verts to lists instead of a mesh, convert to a mesh later
|
||||
- use new index mapping feature of mesh to re-map faces that were not added.
|
||||
|
||||
0.97 by Campbell Barton<br>
|
||||
- Strip material names of spaces
|
||||
- Added import as instance to import the 3ds into its own
|
||||
scene and add a group instance to the current scene
|
||||
- New option to scale down imported objects so they are within a limited bounding area.
|
||||
|
||||
0.96 by Campbell Barton<br>
|
||||
- Added workaround for bug in setting UV's for Zero vert index UV faces.
|
||||
- Removed unique name function, let blender make the names unique.
|
||||
|
||||
0.95 by Campbell Barton<br>
|
||||
- Removed workarounds for Blender 2.41
|
||||
- Mesh objects split by material- many 3ds objects used more then 16 per mesh.
|
||||
- Removed a lot of unneeded variable creation.
|
||||
|
||||
0.94 by Campbell Barton<br>
|
||||
- Face import tested to be about overall 16x speedup over 0.93.
|
||||
- Material importing speedup.
|
||||
- Tested with more models.
|
||||
- Support some corrupt models.
|
||||
|
||||
0.93 by Campbell Barton<br>
|
||||
- Tested with 400 3ds files from turbosquid and samples.
|
||||
- Tactfully ignore faces that used the same verts twice.
|
||||
- Rollback to 0.83 sloppy un-reorganized code, this broke UV coord loading.
|
||||
- Converted from NMesh to Mesh.
|
||||
- Faster and cleaner new names.
|
||||
- Use external comprehensive image loader.
|
||||
- Re intergrated 0.92 and 0.9 changes
|
||||
- Fixes for 2.41 compat.
|
||||
- Non textured faces do not use a texture flag.
|
||||
|
||||
0.92<br>
|
||||
- Added support for diffuse, alpha, spec, bump maps in a single material
|
||||
|
||||
0.9<br>
|
||||
- Reorganized code into object/material block functions<br>
|
||||
- Use of Matrix() to copy matrix data<br>
|
||||
- added support for material transparency<br>
|
||||
|
||||
0.83 2005-08-07: Campell Barton
|
||||
- Aggressive image finding and case insensitivy for posisx systems.
|
||||
|
||||
0.82a 2005-07-22
|
||||
- image texture loading (both for face uv and renderer)
|
||||
|
||||
0.82 - image texture loading (for face uv)
|
||||
|
||||
0.81a (fork- not 0.9) Campbell Barton 2005-06-08
|
||||
- Simplified import code
|
||||
- Never overwrite data
|
||||
- Faster list handling
|
||||
- Leaves import selected
|
||||
|
||||
0.81 Damien McGinnes 2005-01-09
|
||||
- handle missing images better
|
||||
|
||||
0.8 Damien McGinnes 2005-01-08
|
||||
- copies sticky UV coords to face ones
|
||||
- handles images better
|
||||
- Recommend that you run 'RemoveDoubles' on each imported mesh after using this script
|
||||
|
||||
'''
|
||||
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# Script copyright (C) Bob Holcomb
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENCE BLOCK *****
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
# Importing modules
|
||||
# Contributors: Bob Holcomb, Richard L?rk?ng, Damien McGinnes, Campbell Barton, Mario Lapin
|
||||
|
||||
import os
|
||||
import time
|
||||
import struct
|
||||
|
||||
from import_scene_obj import load_image
|
||||
from io_utils import load_image
|
||||
|
||||
import bpy
|
||||
import mathutils
|
||||
@ -158,9 +42,9 @@ BOUNDS_3DS = []
|
||||
PRIMARY = int('0x4D4D',16)
|
||||
|
||||
#------ Main Chunks
|
||||
OBJECTINFO = int('0x3D3D',16); #This gives the version of the mesh and is found right before the material and object information
|
||||
VERSION = int('0x0002',16); #This gives the version of the .3ds file
|
||||
EDITKEYFRAME= int('0xB000',16); #This is the header for all of the key frame info
|
||||
OBJECTINFO = 0x3D3D #This gives the version of the mesh and is found right before the material and object information
|
||||
VERSION = 0x0002 #This gives the version of the .3ds file
|
||||
EDITKEYFRAME= 0xB000 #This is the header for all of the key frame info
|
||||
|
||||
#------ sub defines of OBJECTINFO
|
||||
MATERIAL = 45055 #0xAFFF // This stored the texture info
|
||||
@ -168,62 +52,62 @@ OBJECT = 16384 #0x4000 // This stores the faces, vertices, etc...
|
||||
|
||||
#>------ sub defines of MATERIAL
|
||||
#------ sub defines of MATERIAL_BLOCK
|
||||
MAT_NAME = int('0xA000',16) # This holds the material name
|
||||
MAT_AMBIENT = int('0xA010',16) # Ambient color of the object/material
|
||||
MAT_DIFFUSE = int('0xA020',16) # This holds the color of the object/material
|
||||
MAT_SPECULAR = int('0xA030',16) # SPecular color of the object/material
|
||||
MAT_SHINESS = int('0xA040',16) # ??
|
||||
MAT_TRANSPARENCY= int('0xA050',16) # Transparency value of material
|
||||
MAT_SELF_ILLUM = int('0xA080',16) # Self Illumination value of material
|
||||
MAT_WIRE = int('0xA085',16) # Only render's wireframe
|
||||
MAT_NAME = 0xA000 # This holds the material name
|
||||
MAT_AMBIENT = 0xA010 # Ambient color of the object/material
|
||||
MAT_DIFFUSE = 0xA020 # This holds the color of the object/material
|
||||
MAT_SPECULAR = 0xA030 # SPecular color of the object/material
|
||||
MAT_SHINESS = 0xA040 # ??
|
||||
MAT_TRANSPARENCY= 0xA050 # Transparency value of material
|
||||
MAT_SELF_ILLUM = 0xA080 # Self Illumination value of material
|
||||
MAT_WIRE = 0xA085 # Only render's wireframe
|
||||
|
||||
MAT_TEXTURE_MAP = int('0xA200',16) # This is a header for a new texture map
|
||||
MAT_SPECULAR_MAP= int('0xA204',16) # This is a header for a new specular map
|
||||
MAT_OPACITY_MAP = int('0xA210',16) # This is a header for a new opacity map
|
||||
MAT_REFLECTION_MAP= int('0xA220',16) # This is a header for a new reflection map
|
||||
MAT_BUMP_MAP = int('0xA230',16) # This is a header for a new bump map
|
||||
MAT_MAP_FILENAME = int('0xA300',16) # This holds the file name of the texture
|
||||
MAT_TEXTURE_MAP = 0xA200 # This is a header for a new texture map
|
||||
MAT_SPECULAR_MAP= 0xA204 # This is a header for a new specular map
|
||||
MAT_OPACITY_MAP = 0xA210 # This is a header for a new opacity map
|
||||
MAT_REFLECTION_MAP= 0xA220 # This is a header for a new reflection map
|
||||
MAT_BUMP_MAP = 0xA230 # This is a header for a new bump map
|
||||
MAT_MAP_FILEPATH = 0xA300 # This holds the file name of the texture
|
||||
|
||||
MAT_FLOAT_COLOR = int ('0x0010', 16) #color defined as 3 floats
|
||||
MAT_24BIT_COLOR = int ('0x0011', 16) #color defined as 3 bytes
|
||||
MAT_FLOAT_COLOR = 0x0010 #color defined as 3 floats
|
||||
MAT_24BIT_COLOR = 0x0011 #color defined as 3 bytes
|
||||
|
||||
#>------ sub defines of OBJECT
|
||||
OBJECT_MESH = int('0x4100',16); # This lets us know that we are reading a new object
|
||||
OBJECT_LAMP = int('0x4600',16); # This lets un know we are reading a light object
|
||||
OBJECT_LAMP_SPOT = int('0x4610',16); # The light is a spotloght.
|
||||
OBJECT_LAMP_OFF = int('0x4620',16); # The light off.
|
||||
OBJECT_LAMP_ATTENUATE = int('0x4625',16);
|
||||
OBJECT_LAMP_RAYSHADE = int('0x4627',16);
|
||||
OBJECT_LAMP_SHADOWED = int('0x4630',16);
|
||||
OBJECT_LAMP_LOCAL_SHADOW = int('0x4640',16);
|
||||
OBJECT_LAMP_LOCAL_SHADOW2 = int('0x4641',16);
|
||||
OBJECT_LAMP_SEE_CONE = int('0x4650',16);
|
||||
OBJECT_LAMP_SPOT_RECTANGULAR = int('0x4651',16);
|
||||
OBJECT_LAMP_SPOT_OVERSHOOT = int('0x4652',16);
|
||||
OBJECT_LAMP_SPOT_PROJECTOR = int('0x4653',16);
|
||||
OBJECT_LAMP_EXCLUDE = int('0x4654',16);
|
||||
OBJECT_LAMP_RANGE = int('0x4655',16);
|
||||
OBJECT_LAMP_ROLL = int('0x4656',16);
|
||||
OBJECT_LAMP_SPOT_ASPECT = int('0x4657',16);
|
||||
OBJECT_LAMP_RAY_BIAS = int('0x4658',16);
|
||||
OBJECT_LAMP_INNER_RANGE = int('0x4659',16);
|
||||
OBJECT_LAMP_OUTER_RANGE = int('0x465A',16);
|
||||
OBJECT_LAMP_MULTIPLIER = int('0x465B',16);
|
||||
OBJECT_LAMP_AMBIENT_LIGHT = int('0x4680',16);
|
||||
OBJECT_MESH = 0x4100 # This lets us know that we are reading a new object
|
||||
OBJECT_LAMP = 0x4600 # This lets un know we are reading a light object
|
||||
OBJECT_LAMP_SPOT = 0x4610 # The light is a spotloght.
|
||||
OBJECT_LAMP_OFF = 0x4620 # The light off.
|
||||
OBJECT_LAMP_ATTENUATE = 0x4625
|
||||
OBJECT_LAMP_RAYSHADE = 0x4627
|
||||
OBJECT_LAMP_SHADOWED = 0x4630
|
||||
OBJECT_LAMP_LOCAL_SHADOW = 0x4640
|
||||
OBJECT_LAMP_LOCAL_SHADOW2 = 0x4641
|
||||
OBJECT_LAMP_SEE_CONE = 0x4650
|
||||
OBJECT_LAMP_SPOT_RECTANGULAR = 0x4651
|
||||
OBJECT_LAMP_SPOT_OVERSHOOT = 0x4652
|
||||
OBJECT_LAMP_SPOT_PROJECTOR = 0x4653
|
||||
OBJECT_LAMP_EXCLUDE = 0x4654
|
||||
OBJECT_LAMP_RANGE = 0x4655
|
||||
OBJECT_LAMP_ROLL = 0x4656
|
||||
OBJECT_LAMP_SPOT_ASPECT = 0x4657
|
||||
OBJECT_LAMP_RAY_BIAS = 0x4658
|
||||
OBJECT_LAMP_INNER_RANGE = 0x4659
|
||||
OBJECT_LAMP_OUTER_RANGE = 0x465A
|
||||
OBJECT_LAMP_MULTIPLIER = 0x465B
|
||||
OBJECT_LAMP_AMBIENT_LIGHT = 0x4680
|
||||
|
||||
|
||||
|
||||
OBJECT_CAMERA= int('0x4700',16); # This lets un know we are reading a camera object
|
||||
OBJECT_CAMERA= 0x4700 # This lets un know we are reading a camera object
|
||||
|
||||
#>------ sub defines of CAMERA
|
||||
OBJECT_CAM_RANGES= int('0x4720',16); # The camera range values
|
||||
OBJECT_CAM_RANGES= 0x4720 # The camera range values
|
||||
|
||||
#>------ sub defines of OBJECT_MESH
|
||||
OBJECT_VERTICES = int('0x4110',16); # The objects vertices
|
||||
OBJECT_FACES = int('0x4120',16); # The objects faces
|
||||
OBJECT_MATERIAL = int('0x4130',16); # This is found if the object has a material, either texture map or color
|
||||
OBJECT_UV = int('0x4140',16); # The UV texture coordinates
|
||||
OBJECT_TRANS_MATRIX = int('0x4160',16); # The Object Matrix
|
||||
OBJECT_VERTICES = 0x4110 # The objects vertices
|
||||
OBJECT_FACES = 0x4120 # The objects faces
|
||||
OBJECT_MATERIAL = 0x4130 # This is found if the object has a material, either texture map or color
|
||||
OBJECT_UV = 0x4140 # The UV texture coordinates
|
||||
OBJECT_TRANS_MATRIX = 0x4160 # The Object Matrix
|
||||
|
||||
global scn
|
||||
scn = None
|
||||
@ -266,12 +150,10 @@ def read_string(file):
|
||||
s += struct.unpack('<c', file.read(1))[0]
|
||||
#print 'string: ',s
|
||||
|
||||
#remove the null character from the string
|
||||
s = str(s[:-1], 'ASCII')
|
||||
# print("read string", s)
|
||||
|
||||
#remove the null character from the string
|
||||
return s
|
||||
# return s[:-1]
|
||||
|
||||
######################################################
|
||||
# IMPORT
|
||||
@ -300,9 +182,20 @@ def add_texture_to_material(image, texture, material, mapto):
|
||||
|
||||
if image:
|
||||
texture.image = image
|
||||
# if image: texture.setImage(image) # double check its an image.
|
||||
|
||||
material.add_texture(texture, "UV", mapto)
|
||||
mtex = material.texture_slots.add()
|
||||
mtex.texture = texture
|
||||
mtex.texture_coords = 'UV'
|
||||
mtex.use_map_color_diffuse = False
|
||||
|
||||
if mapto == 'COLOR':
|
||||
mtex.use_map_color_diffuse = True
|
||||
elif mapto == 'SPECULARITY':
|
||||
mtex.use_map_specular = True
|
||||
elif mapto == 'ALPHA':
|
||||
mtex.use_map_alpha = True
|
||||
elif mapto == 'NORMAL':
|
||||
mtex.use_map_normal = True
|
||||
|
||||
|
||||
def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
@ -337,7 +230,8 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
bmesh = bpy.data.meshes.new(contextObName)
|
||||
if myContextMesh_vertls:
|
||||
|
||||
bmesh.add_geometry(len(myContextMesh_vertls)//3, 0, len(myContextMesh_facels))
|
||||
bmesh.vertices.add(len(myContextMesh_vertls)//3)
|
||||
bmesh.faces.add(len(myContextMesh_facels))
|
||||
bmesh.vertices.foreach_set("co", myContextMesh_vertls)
|
||||
|
||||
eekadoodle_faces = []
|
||||
@ -346,19 +240,20 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
bmesh.faces.foreach_set("vertices_raw", eekadoodle_faces)
|
||||
|
||||
if bmesh.faces and contextMeshUV:
|
||||
bmesh.add_uv_texture()
|
||||
uv_faces = bmesh.active_uv_texture.data[:]
|
||||
bmesh.uv_textures.new()
|
||||
uv_faces = bmesh.uv_textures.active.data[:]
|
||||
else:
|
||||
uv_faces = None
|
||||
|
||||
for mat_idx, (matName, faces) in enumerate(myContextMeshMaterials.items()):
|
||||
if matName is None:
|
||||
bmesh.add_material(None)
|
||||
bmat = None
|
||||
else:
|
||||
bmat = MATDICT[matName][1]
|
||||
bmesh.add_material(bmat) # can be None
|
||||
img = TEXTURE_DICT.get(bmat.name)
|
||||
|
||||
|
||||
bmesh.materials.append(bmat) # can be None
|
||||
|
||||
if uv_faces and img:
|
||||
for fidx in faces:
|
||||
bmesh.faces[fidx].material_index = mat_idx
|
||||
@ -414,16 +309,14 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
return [float(col)/255 for col in struct.unpack('<3B', temp_data)] # data [0,1,2] == rgb
|
||||
|
||||
def read_texture(new_chunk, temp_chunk, name, mapto):
|
||||
new_texture = bpy.data.textures.new(name)
|
||||
new_texture.type = 'IMAGE'
|
||||
new_texture = new_texture.recast_type()
|
||||
new_texture = bpy.data.textures.new(name, type='IMAGE')
|
||||
|
||||
img = None
|
||||
while (new_chunk.bytes_read < new_chunk.length):
|
||||
#print 'MAT_TEXTURE_MAP..while', new_chunk.bytes_read, new_chunk.length
|
||||
read_chunk(file, temp_chunk)
|
||||
|
||||
if (temp_chunk.ID == MAT_MAP_FILENAME):
|
||||
if (temp_chunk.ID == MAT_MAP_FILEPATH):
|
||||
texture_name = read_string(file)
|
||||
img = TEXTURE_DICT[contextMaterial.name] = load_image(texture_name, dirname)
|
||||
new_chunk.bytes_read += (len(texture_name)+1) #plus one for the null character that gets removed
|
||||
@ -437,7 +330,7 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
if img:
|
||||
add_texture_to_material(img, new_texture, contextMaterial, mapto)
|
||||
|
||||
dirname = os.path.dirname(FILENAME)
|
||||
dirname = os.path.dirname(file.name)
|
||||
|
||||
#loop through all the data for this chunk (previous chunk) and see what it is
|
||||
while (previous_chunk.bytes_read < previous_chunk.length):
|
||||
@ -723,14 +616,14 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
#contextMatrix = contextMatrix * tx
|
||||
#contextMatrix = contextMatrix *tx
|
||||
|
||||
elif (new_chunk.ID == MAT_MAP_FILENAME):
|
||||
elif (new_chunk.ID == MAT_MAP_FILEPATH):
|
||||
texture_name = read_string(file)
|
||||
try:
|
||||
TEXTURE_DICT[contextMaterial.name]
|
||||
except:
|
||||
#img = TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME)
|
||||
#img = TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILEPATH)
|
||||
img = TEXTURE_DICT[contextMaterial.name] = load_image(texture_name, dirname)
|
||||
# img = TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILENAME, PLACE_HOLDER=False, RECURSIVE=IMAGE_SEARCH)
|
||||
# img = TEXTURE_DICT[contextMaterial.name]= BPyImage.comprehensiveImageLoad(texture_name, FILEPATH, PLACE_HOLDER=False, RECURSIVE=IMAGE_SEARCH)
|
||||
|
||||
new_chunk.bytes_read += len(texture_name)+1 #plus one for the null character that gets removed
|
||||
|
||||
@ -753,30 +646,27 @@ def process_next_chunk(file, previous_chunk, importedObjects, IMAGE_SEARCH):
|
||||
if CreateBlenderObject:
|
||||
putContextMesh(contextMesh_vertls, contextMesh_facels, contextMeshMaterials)
|
||||
|
||||
def load_3ds(filename, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True, APPLY_MATRIX=False):
|
||||
global FILENAME, SCN
|
||||
# global FILENAME, SCN_OBJECTS
|
||||
def load_3ds(filepath, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True, APPLY_MATRIX=False):
|
||||
global SCN
|
||||
|
||||
# XXX
|
||||
# if BPyMessages.Error_NoFile(filename):
|
||||
# if BPyMessages.Error_NoFile(filepath):
|
||||
# return
|
||||
|
||||
print('\n\nImporting 3DS: "%s"' % (filename))
|
||||
# print('\n\nImporting 3DS: "%s"' % (Blender.sys.expandpath(filename)))
|
||||
print('\n\nImporting 3DS: %r' % (filepath))
|
||||
|
||||
time1 = time.clock()
|
||||
# time1 = Blender.sys.time()
|
||||
|
||||
FILENAME = filename
|
||||
current_chunk = chunk()
|
||||
|
||||
file = open(filename,'rb')
|
||||
file = open(filepath, 'rb')
|
||||
|
||||
#here we go!
|
||||
# print 'reading the first chunk'
|
||||
read_chunk(file, current_chunk)
|
||||
if (current_chunk.ID!=PRIMARY):
|
||||
print('\tFatal Error: Not a valid 3ds file: ', filename)
|
||||
print('\tFatal Error: Not a valid 3ds file: %r' % filepath)
|
||||
file.close()
|
||||
return
|
||||
|
||||
@ -837,7 +727,7 @@ def load_3ds(filename, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True,
|
||||
# Done DUMMYVERT
|
||||
"""
|
||||
if IMPORT_AS_INSTANCE:
|
||||
name = filename.split('\\')[-1].split('/')[-1]
|
||||
name = filepath.split('\\')[-1].split('/')[-1]
|
||||
# Create a group for this import.
|
||||
group_scn = Scene.New(name)
|
||||
for ob in importedObjects:
|
||||
@ -895,96 +785,10 @@ def load_3ds(filename, context, IMPORT_CONSTRAIN_BOUNDS=10.0, IMAGE_SEARCH=True,
|
||||
# Done constraining to bounds.
|
||||
|
||||
# Select all new objects.
|
||||
print('finished importing: "%s" in %.4f sec.' % (filename, (time.clock()-time1)))
|
||||
# print('finished importing: "%s" in %.4f sec.' % (filename, (Blender.sys.time()-time1)))
|
||||
print('finished importing: %r in %.4f sec.' % (filepath, (time.clock()-time1)))
|
||||
file.close()
|
||||
|
||||
|
||||
DEBUG = False
|
||||
# For testing compatibility
|
||||
#load_3ds('/metavr/convert/vehicle/truck_002/TruckTanker1.3DS', False)
|
||||
#load_3ds('/metavr/archive/convert/old/arranged_3ds_to_hpx-2/only-need-engine-trains/Engine2.3DS', False)
|
||||
'''
|
||||
|
||||
else:
|
||||
import os
|
||||
# DEBUG ONLY
|
||||
TIME = Blender.sys.time()
|
||||
import os
|
||||
print 'Searching for files'
|
||||
os.system('find /metavr/ -iname "*.3ds" > /tmp/temp3ds_list')
|
||||
# os.system('find /storage/ -iname "*.3ds" > /tmp/temp3ds_list')
|
||||
print '...Done'
|
||||
file = open('/tmp/temp3ds_list', 'r')
|
||||
lines = file.readlines()
|
||||
file.close()
|
||||
# sort by filesize for faster testing
|
||||
lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines]
|
||||
lines_size.sort()
|
||||
lines = [f[1] for f in lines_size]
|
||||
|
||||
|
||||
def between(v,a,b):
|
||||
if v <= max(a,b) and v >= min(a,b):
|
||||
return True
|
||||
return False
|
||||
|
||||
for i, _3ds in enumerate(lines):
|
||||
if between(i, 650,800):
|
||||
#_3ds= _3ds[:-1]
|
||||
print 'Importing', _3ds, '\nNUMBER', i, 'of', len(lines)
|
||||
_3ds_file= _3ds.split('/')[-1].split('\\')[-1]
|
||||
newScn = Blender.Scene.New(_3ds_file)
|
||||
newScn.makeCurrent()
|
||||
load_3ds(_3ds, False)
|
||||
|
||||
print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
|
||||
|
||||
'''
|
||||
from bpy.props import *
|
||||
|
||||
|
||||
class IMPORT_OT_autodesk_3ds(bpy.types.Operator):
|
||||
'''Import from 3DS file format (.3ds)'''
|
||||
bl_idname = "import_scene.autodesk_3ds"
|
||||
bl_label = 'Import 3DS'
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
filepath = StringProperty(name="File Path", description="Filepath used for importing the 3DS file", maxlen= 1024, default= "")
|
||||
|
||||
constrain_size = FloatProperty(name="Size Constraint", description="Scale the model by 10 until it reacehs the size constraint. Zero Disables.", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=10.0)
|
||||
search_images = BoolProperty(name="Image Search", description="Search subdirectories for any assosiated images (Warning, may be slow)", default=True)
|
||||
apply_transform = BoolProperty(name="Apply Transform", description="Workaround for object transformations importing incorrectly", default=False)
|
||||
|
||||
def execute(self, context):
|
||||
load_3ds(self.properties.filepath,
|
||||
context,
|
||||
IMPORT_CONSTRAIN_BOUNDS=self.properties.constrain_size,
|
||||
IMAGE_SEARCH=self.properties.search_images,
|
||||
APPLY_MATRIX=self.properties.apply_transform)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm.add_fileselect(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(IMPORT_OT_autodesk_3ds.bl_idname, text="3D Studio (.3ds)")
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_import.append(menu_func)
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_import.remove(menu_func)
|
||||
|
||||
# NOTES:
|
||||
# why add 1 extra vertex? and remove it when done? - "Answer - eekadoodle - would need to re-order UV's without this since face order isnt always what we give blender, BMesh will solve :D"
|
||||
# disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
def load(operator, context, filepath="", constrain_size=0.0, use_image_search=True, use_apply_transform=True):
|
||||
load_3ds(filepath, context, IMPORT_CONSTRAIN_BOUNDS=constrain_size, IMAGE_SEARCH=use_image_search, APPLY_MATRIX=use_apply_transform)
|
||||
return {'FINISHED'}
|
102
release/scripts/op/io_scene_fbx/__init__.py
Normal file
102
release/scripts/op/io_scene_fbx/__init__.py
Normal file
@ -0,0 +1,102 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||
if "bpy" in locals():
|
||||
# only reload if we alredy loaded, highly annoying
|
||||
import sys
|
||||
reload(sys.modules.get("io_scene_fbx.export_fbx", sys))
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy.props import *
|
||||
from io_utils import ExportHelper
|
||||
|
||||
|
||||
class ExportFBX(bpy.types.Operator, ExportHelper):
|
||||
'''Selection to an ASCII Autodesk FBX'''
|
||||
bl_idname = "export_scene.fbx"
|
||||
bl_label = "Export FBX"
|
||||
|
||||
filename_ext = ".fbx"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
EXP_OBS_SELECTED = BoolProperty(name="Selected Objects", description="Export selected objects on visible layers", default=True)
|
||||
# EXP_OBS_SCENE = BoolProperty(name="Scene Objects", description="Export all objects in this scene", default=True)
|
||||
TX_SCALE = FloatProperty(name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0)
|
||||
TX_XROT90 = BoolProperty(name="Rot X90", description="Rotate all objects 90 degrees about the X axis", default=True)
|
||||
TX_YROT90 = BoolProperty(name="Rot Y90", description="Rotate all objects 90 degrees about the Y axis", default=False)
|
||||
TX_ZROT90 = BoolProperty(name="Rot Z90", description="Rotate all objects 90 degrees about the Z axis", default=False)
|
||||
EXP_EMPTY = BoolProperty(name="Empties", description="Export empty objects", default=True)
|
||||
EXP_CAMERA = BoolProperty(name="Cameras", description="Export camera objects", default=True)
|
||||
EXP_LAMP = BoolProperty(name="Lamps", description="Export lamp objects", default=True)
|
||||
EXP_ARMATURE = BoolProperty(name="Armatures", description="Export armature objects", default=True)
|
||||
EXP_MESH = BoolProperty(name="Meshes", description="Export mesh objects", default=True)
|
||||
EXP_MESH_APPLY_MOD = BoolProperty(name="Modifiers", description="Apply modifiers to mesh objects", default=True)
|
||||
EXP_MESH_HQ_NORMALS = BoolProperty(name="HQ Normals", description="Generate high quality normals", default=True)
|
||||
EXP_IMAGE_COPY = BoolProperty(name="Copy Image Files", description="Copy image files to the destination path", default=False)
|
||||
# armature animation
|
||||
ANIM_ENABLE = BoolProperty(name="Enable Animation", description="Export keyframe animation", default=True)
|
||||
ANIM_OPTIMIZE = BoolProperty(name="Optimize Keyframes", description="Remove double keyframes", default=True)
|
||||
ANIM_OPTIMIZE_PRECISSION = FloatProperty(name="Precision", description="Tolerence for comparing double keyframes (higher for greater accuracy)", min=1, max=16, soft_min=1, soft_max=16, default=6.0)
|
||||
# ANIM_ACTION_ALL = BoolProperty(name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True)
|
||||
ANIM_ACTION_ALL = BoolProperty(name="All Actions", description="Use all actions for armatures, if false, use current action", default=False)
|
||||
# batch
|
||||
BATCH_ENABLE = BoolProperty(name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False)
|
||||
BATCH_GROUP = BoolProperty(name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False)
|
||||
BATCH_OWN_DIR = BoolProperty(name="Own Dir", description="Create a dir for each exported file", default=True)
|
||||
BATCH_FILE_PREFIX = StringProperty(name="Prefix", description="Prefix each file with this name", maxlen=1024, default="")
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
import math
|
||||
from mathutils import Matrix
|
||||
if not self.properties.filepath:
|
||||
raise Exception("filepath not set")
|
||||
|
||||
mtx4_x90n = Matrix.Rotation(-math.pi/2.0, 4, 'X')
|
||||
mtx4_y90n = Matrix.Rotation(-math.pi/2.0, 4, 'Y')
|
||||
mtx4_z90n = Matrix.Rotation(-math.pi/2.0, 4, 'Z')
|
||||
|
||||
GLOBAL_MATRIX = Matrix()
|
||||
GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self.properties.TX_SCALE
|
||||
if self.properties.TX_XROT90: GLOBAL_MATRIX = mtx4_x90n * GLOBAL_MATRIX
|
||||
if self.properties.TX_YROT90: GLOBAL_MATRIX = mtx4_y90n * GLOBAL_MATRIX
|
||||
if self.properties.TX_ZROT90: GLOBAL_MATRIX = mtx4_z90n * GLOBAL_MATRIX
|
||||
|
||||
import io_scene_fbx.export_fbx
|
||||
return io_scene_fbx.export_fbx.save(self, context, GLOBAL_MATRIX=GLOBAL_MATRIX, **self.properties)
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX (.fbx)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
@ -18,36 +18,13 @@
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
__author__ = "Campbell Barton"
|
||||
__url__ = ['www.blender.org', 'blenderartists.org']
|
||||
__version__ = "1.2"
|
||||
# Script copyright (C) Campbell Barton
|
||||
|
||||
__bpydoc__ = """\
|
||||
"""
|
||||
This script is an exporter to the FBX file format.
|
||||
|
||||
http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx
|
||||
"""
|
||||
# --------------------------------------------------------------------------
|
||||
# FBX Export v0.1 by Campbell Barton (AKA Ideasman)
|
||||
# --------------------------------------------------------------------------
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENCE BLOCK *****
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
import time
|
||||
@ -57,19 +34,10 @@ import shutil # for file copying
|
||||
import bpy
|
||||
from mathutils import Vector, Euler, Matrix
|
||||
|
||||
def copy_file(source, dest):
|
||||
# XXX - remove, can use shutil
|
||||
file = open(source, 'rb')
|
||||
data = file.read()
|
||||
file.close()
|
||||
|
||||
file = open(dest, 'wb')
|
||||
file.write(data)
|
||||
file.close()
|
||||
|
||||
|
||||
# XXX not used anymore, images are copied one at a time
|
||||
def copy_images(dest_dir, textures):
|
||||
import shutil
|
||||
|
||||
if not dest_dir.endswith(os.sep):
|
||||
dest_dir += os.sep
|
||||
|
||||
@ -84,12 +52,12 @@ def copy_images(dest_dir, textures):
|
||||
# Make a name for the target path.
|
||||
dest_image_path = dest_dir + image_path.split('\\')[-1].split('/')[-1]
|
||||
if not Blender.sys.exists(dest_image_path): # Image isnt already there
|
||||
print('\tCopying "%s" > "%s"' % (image_path, dest_image_path))
|
||||
print("\tCopying %r > %r" % (image_path, dest_image_path))
|
||||
try:
|
||||
copy_file(image_path, dest_image_path)
|
||||
shutil.copy(image_path, dest_image_path)
|
||||
copyCount+=1
|
||||
except:
|
||||
print('\t\tWarning, file failed to copy, skipping.')
|
||||
print("\t\tWarning, file failed to copy, skipping.")
|
||||
|
||||
print('\tCopied %d images' % copyCount)
|
||||
|
||||
@ -104,27 +72,11 @@ def eulerRadToDeg(eul):
|
||||
|
||||
return ret
|
||||
|
||||
mtx4_identity = Matrix()
|
||||
|
||||
# testing
|
||||
mtx_x90 = Matrix.Rotation( math.pi/2, 3, 'X') # used
|
||||
#mtx_x90n = Matrix.Rotation(-90, 3, 'x')
|
||||
#mtx_y90 = Matrix.Rotation( 90, 3, 'y')
|
||||
#mtx_y90n = Matrix.Rotation(-90, 3, 'y')
|
||||
#mtx_z90 = Matrix.Rotation( 90, 3, 'z')
|
||||
#mtx_z90n = Matrix.Rotation(-90, 3, 'z')
|
||||
|
||||
#mtx4_x90 = Matrix.Rotation( 90, 4, 'x')
|
||||
mtx4_x90n = Matrix.Rotation(-math.pi/2, 4, 'X') # used
|
||||
#mtx4_y90 = Matrix.Rotation( 90, 4, 'y')
|
||||
mtx4_y90n = Matrix.Rotation(-math.pi/2, 4, 'Y') # used
|
||||
mtx4_z90 = Matrix.Rotation( math.pi/2, 4, 'Z') # used
|
||||
mtx4_z90n = Matrix.Rotation(-math.pi/2, 4, 'Z') # used
|
||||
|
||||
# def strip_path(p):
|
||||
# return p.split('\\')[-1].split('/')[-1]
|
||||
|
||||
# Used to add the scene name into the filename without using odd chars
|
||||
# Used to add the scene name into the filepath without using odd chars
|
||||
sane_name_mapping_ob = {}
|
||||
sane_name_mapping_mat = {}
|
||||
sane_name_mapping_tex = {}
|
||||
@ -197,7 +149,7 @@ def sane_groupname(data): return sane_name(data, sane_name_mapping_group)
|
||||
# '''
|
||||
# fname_orig - blender path, can be relative
|
||||
# basepath - fname_rel will be relative to this
|
||||
# FORCE_CWD - dont use the basepath, just add a ./ to the filename.
|
||||
# FORCE_CWD - dont use the basepath, just add a ./ to the filepath.
|
||||
# use when we know the file will be in the basepath.
|
||||
# '''
|
||||
# fname = bpy.path.abspath(fname_orig)
|
||||
@ -282,19 +234,17 @@ header_comment = \
|
||||
|
||||
'''
|
||||
|
||||
# This func can be called with just the filename
|
||||
def write(filename, batch_objects = None, \
|
||||
context = None,
|
||||
# This func can be called with just the filepath
|
||||
def save(operator, context, filepath="", \
|
||||
EXP_OBS_SELECTED = True,
|
||||
EXP_MESH = True,
|
||||
EXP_MESH_APPLY_MOD = True,
|
||||
# EXP_MESH_HQ_NORMALS = False,
|
||||
EXP_ARMATURE = True,
|
||||
EXP_LAMP = True,
|
||||
EXP_CAMERA = True,
|
||||
EXP_EMPTY = True,
|
||||
EXP_IMAGE_COPY = False,
|
||||
GLOBAL_MATRIX = Matrix(),
|
||||
GLOBAL_MATRIX = None,
|
||||
ANIM_ENABLE = True,
|
||||
ANIM_OPTIMIZE = True,
|
||||
ANIM_OPTIMIZE_PRECISSION = 6,
|
||||
@ -305,16 +255,26 @@ def write(filename, batch_objects = None, \
|
||||
BATCH_OWN_DIR = False
|
||||
):
|
||||
|
||||
if bpy.context.object:
|
||||
#XXX, missing arg
|
||||
batch_objects = None
|
||||
|
||||
# testing
|
||||
mtx_x90 = Matrix.Rotation( math.pi/2.0, 3, 'X') # used
|
||||
mtx4_z90 = Matrix.Rotation( math.pi/2.0, 4, 'Z')
|
||||
|
||||
if GLOBAL_MATRIX is None:
|
||||
GLOBAL_MATRIX = Matrix()
|
||||
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
# ----------------- Batch support!
|
||||
if BATCH_ENABLE:
|
||||
if os == None: BATCH_OWN_DIR = False
|
||||
|
||||
fbxpath = filename
|
||||
fbxpath = filepath
|
||||
|
||||
# get the path component of filename
|
||||
# get the path component of filepath
|
||||
tmp_exists = bpy.utils.exists(fbxpath)
|
||||
# tmp_exists = Blender.sys.exists(fbxpath)
|
||||
|
||||
@ -323,7 +283,7 @@ def write(filename, batch_objects = None, \
|
||||
# while fbxpath and fbxpath[-1] not in ('/', '\\'):
|
||||
# fbxpath = fbxpath[:-1]
|
||||
if not fbxpath:
|
||||
# if not filename:
|
||||
# if not filepath:
|
||||
# XXX
|
||||
print('Error%t|Directory does not exist!')
|
||||
# Draw.PupMenu('Error%t|Directory does not exist!')
|
||||
@ -368,9 +328,9 @@ def write(filename, batch_objects = None, \
|
||||
os.mkdir(new_fbxpath)
|
||||
|
||||
|
||||
filename = new_fbxpath + newname + '.fbx'
|
||||
filepath = new_fbxpath + newname + '.fbx'
|
||||
|
||||
print('\nBatch exporting %s as...\n\t"%s"' % (data, filename))
|
||||
print('\nBatch exporting %s as...\n\t%r' % (data, filepath))
|
||||
|
||||
# XXX don't know what to do with this, probably do the same? (Arystan)
|
||||
if BATCH_GROUP: #group
|
||||
@ -393,12 +353,11 @@ def write(filename, batch_objects = None, \
|
||||
|
||||
# Call self with modified args
|
||||
# Dont pass batch options since we already usedt them
|
||||
write(filename, data.objects,
|
||||
write(filepath, data.objects,
|
||||
context,
|
||||
False,
|
||||
EXP_MESH,
|
||||
EXP_MESH_APPLY_MOD,
|
||||
# EXP_MESH_HQ_NORMALS,
|
||||
EXP_ARMATURE,
|
||||
EXP_LAMP,
|
||||
EXP_CAMERA,
|
||||
@ -423,9 +382,9 @@ def write(filename, batch_objects = None, \
|
||||
# end batch support
|
||||
|
||||
# Use this for working out paths relative to the export location
|
||||
basepath = os.path.dirname(filename) or '.'
|
||||
basepath = os.path.dirname(filepath) or '.'
|
||||
basepath += os.sep
|
||||
# basepath = Blender.sys.dirname(filename)
|
||||
# basepath = Blender.sys.dirname(filepath)
|
||||
|
||||
# ----------------------------------------------
|
||||
# storage classes
|
||||
@ -572,11 +531,11 @@ def write(filename, batch_objects = None, \
|
||||
|
||||
|
||||
|
||||
print('\nFBX export starting...', filename)
|
||||
print('\nFBX export starting... %r' % filepath)
|
||||
start_time = time.clock()
|
||||
# start_time = Blender.sys.time()
|
||||
try:
|
||||
file = open(filename, 'w')
|
||||
file = open(filepath, 'w')
|
||||
except:
|
||||
return False
|
||||
|
||||
@ -1630,7 +1589,7 @@ def write(filename, batch_objects = None, \
|
||||
# if me.vertexColors:
|
||||
collayers = me.vertex_colors
|
||||
# collayers = me.getColorLayerNames()
|
||||
collayer_orig = me.active_vertex_color
|
||||
collayer_orig = me.vertex_colors.active
|
||||
# collayer_orig = me.activeColorLayer
|
||||
for colindex, collayer in enumerate(collayers):
|
||||
# me.activeColorLayer = collayer
|
||||
@ -1700,7 +1659,7 @@ def write(filename, batch_objects = None, \
|
||||
if do_uvs:
|
||||
uvlayers = me.uv_textures
|
||||
# uvlayers = me.getUVLayerNames()
|
||||
uvlayer_orig = me.active_uv_texture
|
||||
uvlayer_orig = me.uv_textures.active
|
||||
# uvlayer_orig = me.activeUVLayer
|
||||
for uvindex, uvlayer in enumerate(me.uv_textures):
|
||||
# for uvindex, uvlayer in enumerate(uvlayers):
|
||||
@ -1834,8 +1793,8 @@ def write(filename, batch_objects = None, \
|
||||
|
||||
mats = my_mesh.blenMaterialList
|
||||
|
||||
if me.active_uv_texture:
|
||||
uv_faces = me.active_uv_texture.data
|
||||
if me.uv_textures.active:
|
||||
uv_faces = me.uv_textures.active.data
|
||||
else:
|
||||
uv_faces = [None] * len(me.faces)
|
||||
|
||||
@ -2006,7 +1965,7 @@ def write(filename, batch_objects = None, \
|
||||
ob_base.update(scene)
|
||||
|
||||
# This causes the makeDisplayList command to effect the mesh
|
||||
scene.set_frame(scene.frame_current)
|
||||
scene.frame_set(scene.frame_current)
|
||||
# Blender.Set('curframe', Blender.Get('curframe'))
|
||||
|
||||
|
||||
@ -2103,7 +2062,7 @@ def write(filename, batch_objects = None, \
|
||||
material_mapping_local = {}
|
||||
if len(me.uv_textures) > 0:
|
||||
# if me.faceUV:
|
||||
uvlayer_orig = me.active_uv_texture
|
||||
uvlayer_orig = me.uv_textures.active
|
||||
# uvlayer_orig = me.activeUVLayer
|
||||
for uvlayer in me.uv_textures:
|
||||
# for uvlayer in me.getUVLayerNames():
|
||||
@ -2179,7 +2138,7 @@ def write(filename, batch_objects = None, \
|
||||
if ob_base.type == 'ARMATURE':
|
||||
ob_base.update(scene)
|
||||
# This causes the makeDisplayList command to effect the mesh
|
||||
scene.set_frame(scene.frame_current)
|
||||
scene.frame_set(scene.frame_current)
|
||||
# Blender.Set('curframe', Blender.Get('curframe'))
|
||||
|
||||
del tmp_ob_type, tmp_objects
|
||||
@ -2472,7 +2431,7 @@ Objects: {''')
|
||||
file.write('\n\t\tPoseNode: {')
|
||||
file.write('\n\t\t\tNode: "Model::%s"' % fbxName )
|
||||
if matrix: file.write('\n\t\t\tMatrix: %s' % mat4x4str(matrix))
|
||||
else: file.write('\n\t\t\tMatrix: %s' % mat4x4str(mtx4_identity))
|
||||
else: file.write('\n\t\t\tMatrix: %s' % mat4x4str(Matrix()))
|
||||
file.write('\n\t\t}')
|
||||
|
||||
file.write('\n\t}')
|
||||
@ -2760,7 +2719,9 @@ Takes: {''')
|
||||
else:
|
||||
file.write('\n\tTake: "%s" {' % sane_takename(blenAction))
|
||||
|
||||
act_start, act_end = blenAction.get_frame_range()
|
||||
act_start, act_end = blenAction.frame_range
|
||||
act_start = int(act_start)
|
||||
act_end = int(act_end)
|
||||
# tmp = blenAction.getFrameNumbers()
|
||||
# if tmp:
|
||||
# act_start = min(tmp)
|
||||
@ -2797,7 +2758,7 @@ Takes: {''')
|
||||
'''
|
||||
i = act_start
|
||||
while i <= act_end:
|
||||
scene.set_frame(i)
|
||||
scene.frame_set(i)
|
||||
# Blender.Set('curframe', i)
|
||||
for ob_generic in ob_anim_lists:
|
||||
for my_ob in ob_generic:
|
||||
@ -2937,8 +2898,7 @@ Takes: {''')
|
||||
|
||||
file.write('\n}')
|
||||
|
||||
scene.set_frame(frame_orig)
|
||||
# Blender.Set('curframe', frame_orig)
|
||||
scene.frame_set(frame_orig)
|
||||
|
||||
else:
|
||||
# no animation
|
||||
@ -2961,18 +2921,16 @@ Takes: {''')
|
||||
|
||||
# --------------------------- Footer
|
||||
if world:
|
||||
m = world.mist
|
||||
m = world.mist_settings
|
||||
has_mist = m.use_mist
|
||||
mist_intense = m.intensity
|
||||
mist_start = m.start
|
||||
mist_end = m.depth
|
||||
mist_height = m.height
|
||||
# mist_intense, mist_start, mist_end, mist_height = world.mist
|
||||
world_hor = world.horizon_color
|
||||
# world_hor = world.hor
|
||||
else:
|
||||
has_mist = mist_intense = mist_start = mist_end = mist_height = 0
|
||||
world_hor = 0,0,0
|
||||
world_hor = 0, 0, 0
|
||||
|
||||
file.write('\n;Version 5 settings')
|
||||
file.write('\n;------------------------------------------------------------------')
|
||||
@ -3024,394 +2982,7 @@ Takes: {''')
|
||||
# bpy.util.copy_images( [ tex[1] for tex in textures if tex[1] != None ], basepath)
|
||||
|
||||
print('export finished in %.4f sec.' % (time.clock() - start_time))
|
||||
# print 'export finished in %.4f sec.' % (Blender.sys.time() - start_time)
|
||||
return True
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# UI Function - not a part of the exporter.
|
||||
# this is to separate the user interface from the rest of the exporter.
|
||||
# from Blender import Draw, Window
|
||||
EVENT_NONE = 0
|
||||
EVENT_EXIT = 1
|
||||
EVENT_REDRAW = 2
|
||||
EVENT_FILESEL = 3
|
||||
|
||||
GLOBALS = {}
|
||||
|
||||
# export opts
|
||||
|
||||
def do_redraw(e,v): GLOBALS['EVENT'] = e
|
||||
|
||||
# toggle between these 2, only allow one on at once
|
||||
def do_obs_sel(e,v):
|
||||
GLOBALS['EVENT'] = e
|
||||
GLOBALS['EXP_OBS_SCENE'].val = 0
|
||||
GLOBALS['EXP_OBS_SELECTED'].val = 1
|
||||
|
||||
def do_obs_sce(e,v):
|
||||
GLOBALS['EVENT'] = e
|
||||
GLOBALS['EXP_OBS_SCENE'].val = 1
|
||||
GLOBALS['EXP_OBS_SELECTED'].val = 0
|
||||
|
||||
def do_batch_type_grp(e,v):
|
||||
GLOBALS['EVENT'] = e
|
||||
GLOBALS['BATCH_GROUP'].val = 1
|
||||
GLOBALS['BATCH_SCENE'].val = 0
|
||||
|
||||
def do_batch_type_sce(e,v):
|
||||
GLOBALS['EVENT'] = e
|
||||
GLOBALS['BATCH_GROUP'].val = 0
|
||||
GLOBALS['BATCH_SCENE'].val = 1
|
||||
|
||||
def do_anim_act_all(e,v):
|
||||
GLOBALS['EVENT'] = e
|
||||
GLOBALS['ANIM_ACTION_ALL'][0].val = 1
|
||||
GLOBALS['ANIM_ACTION_ALL'][1].val = 0
|
||||
|
||||
def do_anim_act_cur(e,v):
|
||||
if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val:
|
||||
Draw.PupMenu('Warning%t|Cant use this with batch export group option')
|
||||
else:
|
||||
GLOBALS['EVENT'] = e
|
||||
GLOBALS['ANIM_ACTION_ALL'][0].val = 0
|
||||
GLOBALS['ANIM_ACTION_ALL'][1].val = 1
|
||||
|
||||
def fbx_ui_exit(e,v):
|
||||
GLOBALS['EVENT'] = e
|
||||
|
||||
def do_help(e,v):
|
||||
url = 'http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx'
|
||||
print('Trying to open web browser with documentation at this address...')
|
||||
print('\t' + url)
|
||||
|
||||
try:
|
||||
import webbrowser
|
||||
webbrowser.open(url)
|
||||
except:
|
||||
Blender.Draw.PupMenu("Error%t|Opening a webbrowser requires a full python installation")
|
||||
print('...could not open a browser window.')
|
||||
|
||||
|
||||
|
||||
# run when export is pressed
|
||||
#def fbx_ui_write(e,v):
|
||||
def fbx_ui_write(filename, context):
|
||||
|
||||
# Dont allow overwriting files when saving normally
|
||||
if not GLOBALS['BATCH_ENABLE'].val:
|
||||
if not BPyMessages.Warning_SaveOver(filename):
|
||||
return
|
||||
|
||||
GLOBALS['EVENT'] = EVENT_EXIT
|
||||
|
||||
# Keep the order the same as above for simplicity
|
||||
# the [] is a dummy arg used for objects
|
||||
|
||||
Blender.Window.WaitCursor(1)
|
||||
|
||||
# Make the matrix
|
||||
GLOBAL_MATRIX = mtx4_identity
|
||||
GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = GLOBALS['_SCALE'].val
|
||||
if GLOBALS['_XROT90'].val: GLOBAL_MATRIX = mtx4_x90n * GLOBAL_MATRIX
|
||||
if GLOBALS['_YROT90'].val: GLOBAL_MATRIX = mtx4_y90n * GLOBAL_MATRIX
|
||||
if GLOBALS['_ZROT90'].val: GLOBAL_MATRIX = mtx4_z90n * GLOBAL_MATRIX
|
||||
|
||||
ret = write(\
|
||||
filename, None,\
|
||||
context,
|
||||
GLOBALS['EXP_OBS_SELECTED'].val,\
|
||||
GLOBALS['EXP_MESH'].val,\
|
||||
GLOBALS['EXP_MESH_APPLY_MOD'].val,\
|
||||
GLOBALS['EXP_MESH_HQ_NORMALS'].val,\
|
||||
GLOBALS['EXP_ARMATURE'].val,\
|
||||
GLOBALS['EXP_LAMP'].val,\
|
||||
GLOBALS['EXP_CAMERA'].val,\
|
||||
GLOBALS['EXP_EMPTY'].val,\
|
||||
GLOBALS['EXP_IMAGE_COPY'].val,\
|
||||
GLOBAL_MATRIX,\
|
||||
GLOBALS['ANIM_ENABLE'].val,\
|
||||
GLOBALS['ANIM_OPTIMIZE'].val,\
|
||||
GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val,\
|
||||
GLOBALS['ANIM_ACTION_ALL'][0].val,\
|
||||
GLOBALS['BATCH_ENABLE'].val,\
|
||||
GLOBALS['BATCH_GROUP'].val,\
|
||||
GLOBALS['BATCH_SCENE'].val,\
|
||||
GLOBALS['BATCH_FILE_PREFIX'].val,\
|
||||
GLOBALS['BATCH_OWN_DIR'].val,\
|
||||
)
|
||||
|
||||
Blender.Window.WaitCursor(0)
|
||||
GLOBALS.clear()
|
||||
|
||||
if ret == False:
|
||||
Draw.PupMenu('Error%t|Path cannot be written to!')
|
||||
|
||||
|
||||
def fbx_ui():
|
||||
# Only to center the UI
|
||||
x,y = GLOBALS['MOUSE']
|
||||
x-=180; y-=0 # offset... just to get it centered
|
||||
|
||||
Draw.Label('Export Objects...', x+20,y+165, 200, 20)
|
||||
|
||||
if not GLOBALS['BATCH_ENABLE'].val:
|
||||
Draw.BeginAlign()
|
||||
GLOBALS['EXP_OBS_SELECTED'] = Draw.Toggle('Selected Objects', EVENT_REDRAW, x+20, y+145, 160, 20, GLOBALS['EXP_OBS_SELECTED'].val, 'Export selected objects on visible layers', do_obs_sel)
|
||||
GLOBALS['EXP_OBS_SCENE'] = Draw.Toggle('Scene Objects', EVENT_REDRAW, x+180, y+145, 160, 20, GLOBALS['EXP_OBS_SCENE'].val, 'Export all objects in this scene', do_obs_sce)
|
||||
Draw.EndAlign()
|
||||
|
||||
Draw.BeginAlign()
|
||||
GLOBALS['_SCALE'] = Draw.Number('Scale:', EVENT_NONE, x+20, y+120, 140, 20, GLOBALS['_SCALE'].val, 0.01, 1000.0, 'Scale all data, (Note! some imports dont support scaled armatures)')
|
||||
GLOBALS['_XROT90'] = Draw.Toggle('Rot X90', EVENT_NONE, x+160, y+120, 60, 20, GLOBALS['_XROT90'].val, 'Rotate all objects 90 degrees about the X axis')
|
||||
GLOBALS['_YROT90'] = Draw.Toggle('Rot Y90', EVENT_NONE, x+220, y+120, 60, 20, GLOBALS['_YROT90'].val, 'Rotate all objects 90 degrees about the Y axis')
|
||||
GLOBALS['_ZROT90'] = Draw.Toggle('Rot Z90', EVENT_NONE, x+280, y+120, 60, 20, GLOBALS['_ZROT90'].val, 'Rotate all objects 90 degrees about the Z axis')
|
||||
Draw.EndAlign()
|
||||
|
||||
y -= 35
|
||||
|
||||
Draw.BeginAlign()
|
||||
GLOBALS['EXP_EMPTY'] = Draw.Toggle('Empty', EVENT_NONE, x+20, y+120, 60, 20, GLOBALS['EXP_EMPTY'].val, 'Export empty objects')
|
||||
GLOBALS['EXP_CAMERA'] = Draw.Toggle('Camera', EVENT_NONE, x+80, y+120, 60, 20, GLOBALS['EXP_CAMERA'].val, 'Export camera objects')
|
||||
GLOBALS['EXP_LAMP'] = Draw.Toggle('Lamp', EVENT_NONE, x+140, y+120, 60, 20, GLOBALS['EXP_LAMP'].val, 'Export lamp objects')
|
||||
GLOBALS['EXP_ARMATURE'] = Draw.Toggle('Armature', EVENT_NONE, x+200, y+120, 60, 20, GLOBALS['EXP_ARMATURE'].val, 'Export armature objects')
|
||||
GLOBALS['EXP_MESH'] = Draw.Toggle('Mesh', EVENT_REDRAW, x+260, y+120, 80, 20, GLOBALS['EXP_MESH'].val, 'Export mesh objects', do_redraw) #, do_axis_z)
|
||||
Draw.EndAlign()
|
||||
|
||||
if GLOBALS['EXP_MESH'].val:
|
||||
# below mesh but
|
||||
Draw.BeginAlign()
|
||||
GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Toggle('Modifiers', EVENT_NONE, x+260, y+100, 80, 20, GLOBALS['EXP_MESH_APPLY_MOD'].val, 'Apply modifiers to mesh objects') #, do_axis_z)
|
||||
GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Toggle('HQ Normals', EVENT_NONE, x+260, y+80, 80, 20, GLOBALS['EXP_MESH_HQ_NORMALS'].val, 'Generate high quality normals') #, do_axis_z)
|
||||
Draw.EndAlign()
|
||||
|
||||
GLOBALS['EXP_IMAGE_COPY'] = Draw.Toggle('Copy Image Files', EVENT_NONE, x+20, y+80, 160, 20, GLOBALS['EXP_IMAGE_COPY'].val, 'Copy image files to the destination path') #, do_axis_z)
|
||||
|
||||
|
||||
Draw.Label('Export Armature Animation...', x+20,y+45, 300, 20)
|
||||
|
||||
GLOBALS['ANIM_ENABLE'] = Draw.Toggle('Enable Animation', EVENT_REDRAW, x+20, y+25, 160, 20, GLOBALS['ANIM_ENABLE'].val, 'Export keyframe animation', do_redraw)
|
||||
if GLOBALS['ANIM_ENABLE'].val:
|
||||
Draw.BeginAlign()
|
||||
GLOBALS['ANIM_OPTIMIZE'] = Draw.Toggle('Optimize Keyframes', EVENT_REDRAW, x+20, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE'].val, 'Remove double keyframes', do_redraw)
|
||||
if GLOBALS['ANIM_OPTIMIZE'].val:
|
||||
GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Number('Precission: ', EVENT_NONE, x+180, y+0, 160, 20, GLOBALS['ANIM_OPTIMIZE_PRECISSION'].val, 1, 16, 'Tolerence for comparing double keyframes (higher for greater accuracy)')
|
||||
Draw.EndAlign()
|
||||
|
||||
Draw.BeginAlign()
|
||||
GLOBALS['ANIM_ACTION_ALL'][1] = Draw.Toggle('Current Action', EVENT_REDRAW, x+20, y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][1].val, 'Use actions currently applied to the armatures (use scene start/end frame)', do_anim_act_cur)
|
||||
GLOBALS['ANIM_ACTION_ALL'][0] = Draw.Toggle('All Actions', EVENT_REDRAW, x+180,y-25, 160, 20, GLOBALS['ANIM_ACTION_ALL'][0].val, 'Use all actions for armatures', do_anim_act_all)
|
||||
Draw.EndAlign()
|
||||
|
||||
|
||||
Draw.Label('Export Batch...', x+20,y-60, 300, 20)
|
||||
GLOBALS['BATCH_ENABLE'] = Draw.Toggle('Enable Batch', EVENT_REDRAW, x+20, y-80, 160, 20, GLOBALS['BATCH_ENABLE'].val, 'Automate exporting multiple scenes or groups to files', do_redraw)
|
||||
|
||||
if GLOBALS['BATCH_ENABLE'].val:
|
||||
Draw.BeginAlign()
|
||||
GLOBALS['BATCH_GROUP'] = Draw.Toggle('Group > File', EVENT_REDRAW, x+20, y-105, 160, 20, GLOBALS['BATCH_GROUP'].val, 'Export each group as an FBX file', do_batch_type_grp)
|
||||
GLOBALS['BATCH_SCENE'] = Draw.Toggle('Scene > File', EVENT_REDRAW, x+180, y-105, 160, 20, GLOBALS['BATCH_SCENE'].val, 'Export each scene as an FBX file', do_batch_type_sce)
|
||||
|
||||
# Own dir requires OS module
|
||||
if os:
|
||||
GLOBALS['BATCH_OWN_DIR'] = Draw.Toggle('Own Dir', EVENT_NONE, x+20, y-125, 80, 20, GLOBALS['BATCH_OWN_DIR'].val, 'Create a dir for each exported file')
|
||||
GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+100, y-125, 240, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ')
|
||||
else:
|
||||
GLOBALS['BATCH_FILE_PREFIX'] = Draw.String('Prefix: ', EVENT_NONE, x+20, y-125, 320, 20, GLOBALS['BATCH_FILE_PREFIX'].val, 64, 'Prefix each file with this name ')
|
||||
|
||||
|
||||
Draw.EndAlign()
|
||||
|
||||
#y+=80
|
||||
|
||||
'''
|
||||
Draw.BeginAlign()
|
||||
GLOBALS['FILENAME'] = Draw.String('path: ', EVENT_NONE, x+20, y-170, 300, 20, GLOBALS['FILENAME'].val, 64, 'Prefix each file with this name ')
|
||||
Draw.PushButton('..', EVENT_FILESEL, x+320, y-170, 20, 20, 'Select the path', do_redraw)
|
||||
'''
|
||||
# Until batch is added
|
||||
#
|
||||
|
||||
|
||||
#Draw.BeginAlign()
|
||||
Draw.PushButton('Online Help', EVENT_REDRAW, x+20, y-160, 100, 20, 'Open online help in a browser window', do_help)
|
||||
Draw.PushButton('Cancel', EVENT_EXIT, x+130, y-160, 100, 20, 'Exit the exporter', fbx_ui_exit)
|
||||
Draw.PushButton('Export', EVENT_FILESEL, x+240, y-160, 100, 20, 'Export the fbx file', do_redraw)
|
||||
|
||||
#Draw.PushButton('Export', EVENT_EXIT, x+180, y-160, 160, 20, 'Export the fbx file', fbx_ui_write)
|
||||
#Draw.EndAlign()
|
||||
|
||||
# exit when mouse out of the view?
|
||||
# GLOBALS['EVENT'] = EVENT_EXIT
|
||||
|
||||
#def write_ui(filename):
|
||||
def write_ui():
|
||||
|
||||
# globals
|
||||
GLOBALS['EVENT'] = EVENT_REDRAW
|
||||
#GLOBALS['MOUSE'] = Window.GetMouseCoords()
|
||||
GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()]
|
||||
GLOBALS['FILENAME'] = ''
|
||||
'''
|
||||
# IF called from the fileselector
|
||||
if filename == None:
|
||||
GLOBALS['FILENAME'] = filename # Draw.Create(Blender.sys.makename(ext='.fbx'))
|
||||
else:
|
||||
GLOBALS['FILENAME'].val = filename
|
||||
'''
|
||||
GLOBALS['EXP_OBS_SELECTED'] = Draw.Create(1) # dont need 2 variables but just do this for clarity
|
||||
GLOBALS['EXP_OBS_SCENE'] = Draw.Create(0)
|
||||
|
||||
GLOBALS['EXP_MESH'] = Draw.Create(1)
|
||||
GLOBALS['EXP_MESH_APPLY_MOD'] = Draw.Create(1)
|
||||
GLOBALS['EXP_MESH_HQ_NORMALS'] = Draw.Create(0)
|
||||
GLOBALS['EXP_ARMATURE'] = Draw.Create(1)
|
||||
GLOBALS['EXP_LAMP'] = Draw.Create(1)
|
||||
GLOBALS['EXP_CAMERA'] = Draw.Create(1)
|
||||
GLOBALS['EXP_EMPTY'] = Draw.Create(1)
|
||||
GLOBALS['EXP_IMAGE_COPY'] = Draw.Create(0)
|
||||
# animation opts
|
||||
GLOBALS['ANIM_ENABLE'] = Draw.Create(1)
|
||||
GLOBALS['ANIM_OPTIMIZE'] = Draw.Create(1)
|
||||
GLOBALS['ANIM_OPTIMIZE_PRECISSION'] = Draw.Create(4) # decimal places
|
||||
GLOBALS['ANIM_ACTION_ALL'] = [Draw.Create(0), Draw.Create(1)] # not just the current action
|
||||
|
||||
# batch export options
|
||||
GLOBALS['BATCH_ENABLE'] = Draw.Create(0)
|
||||
GLOBALS['BATCH_GROUP'] = Draw.Create(1) # cant have both of these enabled at once.
|
||||
GLOBALS['BATCH_SCENE'] = Draw.Create(0) # see above
|
||||
GLOBALS['BATCH_FILE_PREFIX'] = Draw.Create(Blender.sys.makename(ext='_').split('\\')[-1].split('/')[-1])
|
||||
GLOBALS['BATCH_OWN_DIR'] = Draw.Create(0)
|
||||
# done setting globals
|
||||
|
||||
# Used by the user interface
|
||||
GLOBALS['_SCALE'] = Draw.Create(1.0)
|
||||
GLOBALS['_XROT90'] = Draw.Create(True)
|
||||
GLOBALS['_YROT90'] = Draw.Create(False)
|
||||
GLOBALS['_ZROT90'] = Draw.Create(False)
|
||||
|
||||
# best not do move the cursor
|
||||
# Window.SetMouseCoords(*[i/2 for i in Window.GetScreenSize()])
|
||||
|
||||
# hack so the toggle buttons redraw. this is not nice at all
|
||||
while GLOBALS['EVENT'] != EVENT_EXIT:
|
||||
|
||||
if GLOBALS['BATCH_ENABLE'].val and GLOBALS['BATCH_GROUP'].val and GLOBALS['ANIM_ACTION_ALL'][1].val:
|
||||
#Draw.PupMenu("Warning%t|Cant batch export groups with 'Current Action' ")
|
||||
GLOBALS['ANIM_ACTION_ALL'][0].val = 1
|
||||
GLOBALS['ANIM_ACTION_ALL'][1].val = 0
|
||||
|
||||
if GLOBALS['EVENT'] == EVENT_FILESEL:
|
||||
if GLOBALS['BATCH_ENABLE'].val:
|
||||
txt = 'Batch FBX Dir'
|
||||
name = Blender.sys.expandpath('//')
|
||||
else:
|
||||
txt = 'Export FBX'
|
||||
name = Blender.sys.makename(ext='.fbx')
|
||||
|
||||
Blender.Window.FileSelector(fbx_ui_write, txt, name)
|
||||
#fbx_ui_write('/test.fbx')
|
||||
break
|
||||
|
||||
Draw.UIBlock(fbx_ui, 0)
|
||||
|
||||
|
||||
# GLOBALS.clear()
|
||||
from bpy.props import *
|
||||
class ExportFBX(bpy.types.Operator):
|
||||
'''Selection to an ASCII Autodesk FBX'''
|
||||
bl_idname = "export.fbx"
|
||||
bl_label = "Export FBX"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
|
||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the FBX file", maxlen= 1024, default="")
|
||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
||||
|
||||
EXP_OBS_SELECTED = BoolProperty(name="Selected Objects", description="Export selected objects on visible layers", default=True)
|
||||
# EXP_OBS_SCENE = BoolProperty(name="Scene Objects", description="Export all objects in this scene", default=True)
|
||||
TX_SCALE = FloatProperty(name="Scale", description="Scale all data, (Note! some imports dont support scaled armatures)", min=0.01, max=1000.0, soft_min=0.01, soft_max=1000.0, default=1.0)
|
||||
TX_XROT90 = BoolProperty(name="Rot X90", description="Rotate all objects 90 degrees about the X axis", default=True)
|
||||
TX_YROT90 = BoolProperty(name="Rot Y90", description="Rotate all objects 90 degrees about the Y axis", default=False)
|
||||
TX_ZROT90 = BoolProperty(name="Rot Z90", description="Rotate all objects 90 degrees about the Z axis", default=False)
|
||||
EXP_EMPTY = BoolProperty(name="Empties", description="Export empty objects", default=True)
|
||||
EXP_CAMERA = BoolProperty(name="Cameras", description="Export camera objects", default=True)
|
||||
EXP_LAMP = BoolProperty(name="Lamps", description="Export lamp objects", default=True)
|
||||
EXP_ARMATURE = BoolProperty(name="Armatures", description="Export armature objects", default=True)
|
||||
EXP_MESH = BoolProperty(name="Meshes", description="Export mesh objects", default=True)
|
||||
EXP_MESH_APPLY_MOD = BoolProperty(name="Modifiers", description="Apply modifiers to mesh objects", default=True)
|
||||
EXP_MESH_HQ_NORMALS = BoolProperty(name="HQ Normals", description="Generate high quality normals", default=True)
|
||||
EXP_IMAGE_COPY = BoolProperty(name="Copy Image Files", description="Copy image files to the destination path", default=False)
|
||||
# armature animation
|
||||
ANIM_ENABLE = BoolProperty(name="Enable Animation", description="Export keyframe animation", default=True)
|
||||
ANIM_OPTIMIZE = BoolProperty(name="Optimize Keyframes", description="Remove double keyframes", default=True)
|
||||
ANIM_OPTIMIZE_PRECISSION = FloatProperty(name="Precision", description="Tolerence for comparing double keyframes (higher for greater accuracy)", min=1, max=16, soft_min=1, soft_max=16, default=6.0)
|
||||
# ANIM_ACTION_ALL = BoolProperty(name="Current Action", description="Use actions currently applied to the armatures (use scene start/end frame)", default=True)
|
||||
ANIM_ACTION_ALL = BoolProperty(name="All Actions", description="Use all actions for armatures, if false, use current action", default=False)
|
||||
# batch
|
||||
BATCH_ENABLE = BoolProperty(name="Enable Batch", description="Automate exporting multiple scenes or groups to files", default=False)
|
||||
BATCH_GROUP = BoolProperty(name="Group > File", description="Export each group as an FBX file, if false, export each scene as an FBX file", default=False)
|
||||
BATCH_OWN_DIR = BoolProperty(name="Own Dir", description="Create a dir for each exported file", default=True)
|
||||
BATCH_FILE_PREFIX = StringProperty(name="Prefix", description="Prefix each file with this name", maxlen=1024, default="")
|
||||
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_object
|
||||
|
||||
def execute(self, context):
|
||||
if not self.properties.filepath:
|
||||
raise Exception("filepath not set")
|
||||
|
||||
filepath = self.properties.filepath
|
||||
filepath = bpy.path.ensure_ext(filepath, ".fbx")
|
||||
|
||||
GLOBAL_MATRIX = mtx4_identity
|
||||
GLOBAL_MATRIX[0][0] = GLOBAL_MATRIX[1][1] = GLOBAL_MATRIX[2][2] = self.properties.TX_SCALE
|
||||
if self.properties.TX_XROT90: GLOBAL_MATRIX = mtx4_x90n * GLOBAL_MATRIX
|
||||
if self.properties.TX_YROT90: GLOBAL_MATRIX = mtx4_y90n * GLOBAL_MATRIX
|
||||
if self.properties.TX_ZROT90: GLOBAL_MATRIX = mtx4_z90n * GLOBAL_MATRIX
|
||||
|
||||
write(filepath,
|
||||
None, # XXX
|
||||
context,
|
||||
self.properties.EXP_OBS_SELECTED,
|
||||
self.properties.EXP_MESH,
|
||||
self.properties.EXP_MESH_APPLY_MOD,
|
||||
# self.properties.EXP_MESH_HQ_NORMALS,
|
||||
self.properties.EXP_ARMATURE,
|
||||
self.properties.EXP_LAMP,
|
||||
self.properties.EXP_CAMERA,
|
||||
self.properties.EXP_EMPTY,
|
||||
self.properties.EXP_IMAGE_COPY,
|
||||
GLOBAL_MATRIX,
|
||||
self.properties.ANIM_ENABLE,
|
||||
self.properties.ANIM_OPTIMIZE,
|
||||
self.properties.ANIM_OPTIMIZE_PRECISSION,
|
||||
self.properties.ANIM_ACTION_ALL,
|
||||
self.properties.BATCH_ENABLE,
|
||||
self.properties.BATCH_GROUP,
|
||||
self.properties.BATCH_FILE_PREFIX,
|
||||
self.properties.BATCH_OWN_DIR,
|
||||
)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
import os
|
||||
if not self.properties.is_property_set("filepath"):
|
||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".fbx"
|
||||
|
||||
context.manager.add_fileselect(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
|
||||
|
||||
# if __name__ == "__main__":
|
||||
# bpy.ops.EXPORT_OT_ply(filepath="/tmp/test.ply")
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
# NOTES (all line numbers correspond to original export_fbx.py (under release/scripts)
|
||||
@ -3432,21 +3003,3 @@ class ExportFBX(bpy.types.Operator):
|
||||
# - bpy.sys.time move to bpy.sys.util?
|
||||
# - new scene creation, activation: lines 327-342, 368
|
||||
# - uses bpy.path.abspath, *.relpath - replace at least relpath
|
||||
|
||||
# SMALL or COSMETICAL
|
||||
# - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version')
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX (.fbx)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
144
release/scripts/op/io_scene_obj/__init__.py
Normal file
144
release/scripts/op/io_scene_obj/__init__.py
Normal file
@ -0,0 +1,144 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||
if "bpy" in locals():
|
||||
# only reload if we alredy loaded, highly annoying
|
||||
import sys
|
||||
reload(sys.modules.get("io_scene_obj.import_obj", sys))
|
||||
reload(sys.modules.get("io_scene_obj.export_obj", sys))
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy.props import *
|
||||
from io_utils import ExportHelper, ImportHelper
|
||||
|
||||
|
||||
class ImportOBJ(bpy.types.Operator, ImportHelper):
|
||||
'''Load a Wavefront OBJ File'''
|
||||
bl_idname = "import_scene.obj"
|
||||
bl_label = "Import OBJ"
|
||||
|
||||
filename_ext = ".obj"
|
||||
|
||||
CREATE_SMOOTH_GROUPS = BoolProperty(name="Smooth Groups", description="Surround smooth groups by sharp edges", default= True)
|
||||
CREATE_FGONS = BoolProperty(name="NGons as FGons", description="Import faces with more then 4 verts as fgons", default= True)
|
||||
CREATE_EDGES = BoolProperty(name="Lines as Edges", description="Import lines and faces with 2 verts as edge", default= True)
|
||||
SPLIT_OBJECTS = BoolProperty(name="Object", description="Import OBJ Objects into Blender Objects", default= True)
|
||||
SPLIT_GROUPS = BoolProperty(name="Group", description="Import OBJ Groups into Blender Objects", default= True)
|
||||
# old comment: only used for user feedback
|
||||
# disabled this option because in old code a handler for it disabled SPLIT* params, it's not passed to load_obj
|
||||
# KEEP_VERT_ORDER = BoolProperty(name="Keep Vert Order", description="Keep vert and face order, disables split options, enable for morph targets", default= True)
|
||||
ROTATE_X90 = BoolProperty(name="-X90", description="Rotate X 90.", default= True)
|
||||
CLAMP_SIZE = FloatProperty(name="Clamp Scale", description="Clamp the size to this maximum (Zero to Disable)", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=0.0)
|
||||
POLYGROUPS = BoolProperty(name="Poly Groups", description="Import OBJ groups as vertex groups.", default= True)
|
||||
IMAGE_SEARCH = BoolProperty(name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True)
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
# print("Selected: " + context.active_object.name)
|
||||
import io_scene_obj.import_obj
|
||||
return io_scene_obj.import_obj.load(self, context, **self.properties)
|
||||
'''
|
||||
load_obj(self.properties.filepath,
|
||||
context,
|
||||
self.properties.CLAMP_SIZE,
|
||||
self.properties.CREATE_FGONS,
|
||||
self.properties.CREATE_SMOOTH_GROUPS,
|
||||
self.properties.CREATE_EDGES,
|
||||
self.properties.SPLIT_OBJECTS,
|
||||
self.properties.SPLIT_GROUPS,
|
||||
self.properties.ROTATE_X90,
|
||||
self.properties.IMAGE_SEARCH,
|
||||
self.properties.POLYGROUPS)
|
||||
'''
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class ExportOBJ(bpy.types.Operator, ExportHelper):
|
||||
'''Save a Wavefront OBJ File'''
|
||||
|
||||
bl_idname = "export_scene.obj"
|
||||
bl_label = 'Export OBJ'
|
||||
|
||||
filename_ext = ".obj"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
# context group
|
||||
use_selection = BoolProperty(name="Selection Only", description="Export selected objects only", default= False)
|
||||
use_all_scenes = BoolProperty(name="All Scenes", description="", default= False)
|
||||
use_animation = BoolProperty(name="Animation", description="", default= False)
|
||||
|
||||
# object group
|
||||
use_modifiers = BoolProperty(name="Apply Modifiers", description="Apply modifiers (preview resolution)", default= True)
|
||||
use_rotate_x90 = BoolProperty(name="Rotate X90", description="", default= True)
|
||||
|
||||
# extra data group
|
||||
use_edges = BoolProperty(name="Edges", description="", default=True)
|
||||
use_normals = BoolProperty(name="Normals", description="", default=False)
|
||||
use_hq_normals = BoolProperty(name="High Quality Normals", description="", default=True)
|
||||
use_uvs = BoolProperty(name="UVs", description="", default= True)
|
||||
use_materials = BoolProperty(name="Materials", description="", default=True)
|
||||
copy_images = BoolProperty(name="Copy Images", description="", default=False)
|
||||
use_triangles = BoolProperty(name="Triangulate", description="", default=False)
|
||||
use_vertex_groups = BoolProperty(name="Polygroups", description="", default=False)
|
||||
use_nurbs = BoolProperty(name="Nurbs", description="", default=False)
|
||||
|
||||
# grouping group
|
||||
use_blen_objects = BoolProperty(name="Objects as OBJ Objects", description="", default= True)
|
||||
group_by_object = BoolProperty(name="Objects as OBJ Groups ", description="", default= False)
|
||||
group_by_material = BoolProperty(name="Material Groups", description="", default= False)
|
||||
keep_vertex_order = BoolProperty(name="Keep Vertex Order", description="", default= False)
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
import io_scene_obj.export_obj
|
||||
print(self.properties.keys())
|
||||
return io_scene_obj.export_obj.save(self, context, **self.properties)
|
||||
|
||||
|
||||
def menu_func_import(self, context):
|
||||
self.layout.operator(ImportOBJ.bl_idname, text="Wavefront (.obj)")
|
||||
|
||||
|
||||
def menu_func_export(self, context):
|
||||
self.layout.operator(ExportOBJ.bl_idname, text="Wavefront (.obj)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_import.append(menu_func_import)
|
||||
bpy.types.INFO_MT_file_export.append(menu_func_export)
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_import.remove(menu_func_import)
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func_export)
|
||||
|
||||
|
||||
# CONVERSION ISSUES
|
||||
# - matrix problem
|
||||
# - duplis - only tested dupliverts
|
||||
# - all scenes export
|
||||
# + normals calculation
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
@ -18,23 +18,6 @@
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
__author__ = "Campbell Barton, Jiri Hnidek, Paolo Ciccone"
|
||||
__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org']
|
||||
__version__ = "1.21"
|
||||
|
||||
__bpydoc__ = """\
|
||||
This script is an exporter to OBJ file format.
|
||||
|
||||
Usage:
|
||||
|
||||
Select the objects you wish to export and run this script from "File->Export" menu.
|
||||
Selecting the default options from the popup box will be good in most cases.
|
||||
All objects that can be represented as a mesh (mesh, curve, metaball, surface, text3d)
|
||||
will be exported as mesh data.
|
||||
"""
|
||||
|
||||
# import math and other in functions that use them for the sake of fast Blender startup
|
||||
# import math
|
||||
import os
|
||||
import time
|
||||
import shutil
|
||||
@ -122,7 +105,7 @@ def write_mtl(scene, filepath, copy_images, mtl_dict):
|
||||
try:
|
||||
filepath = copy_image(mtex.texture.image)
|
||||
# filepath = mtex.texture.image.filepath.split('\\')[-1].split('/')[-1]
|
||||
file.write('map_Kd %s\n' % filepath) # Diffuse mapping image
|
||||
file.write('map_Kd %s\n' % repr(filepath)[1:-1]) # Diffuse mapping image
|
||||
break
|
||||
except:
|
||||
# Texture has no image though its an image type, best ignore.
|
||||
@ -184,50 +167,48 @@ def copy_images(dest_dir):
|
||||
# paths= bpy.util.copy_images(uniqueImages.values(), dest_dir)
|
||||
|
||||
print('\tCopied %d images' % copyCount)
|
||||
# print('\tCopied %d images' % copyCount)
|
||||
|
||||
# XXX not converted
|
||||
|
||||
def test_nurbs_compat(ob):
|
||||
if ob.type != 'Curve':
|
||||
if ob.type != 'CURVE':
|
||||
return False
|
||||
|
||||
for nu in ob.data:
|
||||
if (not nu.knotsV) and nu.type != 1: # not a surface and not bezier
|
||||
for nu in ob.data.splines:
|
||||
if nu.point_count_v == 1 and nu.type != 'BEZIER': # not a surface and not bezier
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
# XXX not converted
|
||||
def write_nurb(file, ob, ob_mat):
|
||||
tot_verts = 0
|
||||
cu = ob.data
|
||||
|
||||
# use negative indices
|
||||
Vector = Blender.mathutils.Vector
|
||||
for nu in cu:
|
||||
for nu in cu.splines:
|
||||
if nu.type == 'POLY':
|
||||
DEG_ORDER_U = 1
|
||||
else:
|
||||
DEG_ORDER_U = nu.order_u - 1 # odd but tested to be correct
|
||||
|
||||
if nu.type==0: DEG_ORDER_U = 1
|
||||
else: DEG_ORDER_U = nu.orderU-1 # Tested to be correct
|
||||
|
||||
if nu.type==1:
|
||||
if nu.type == 'BEZIER':
|
||||
print("\tWarning, bezier curve:", ob.name, "only poly and nurbs curves supported")
|
||||
continue
|
||||
|
||||
if nu.knotsV:
|
||||
if nu.point_count_v > 1:
|
||||
print("\tWarning, surface:", ob.name, "only poly and nurbs curves supported")
|
||||
continue
|
||||
|
||||
if len(nu) <= DEG_ORDER_U:
|
||||
print("\tWarning, orderU is lower then vert count, skipping:", ob.name)
|
||||
if len(nu.points) <= DEG_ORDER_U:
|
||||
print("\tWarning, order_u is lower then vert count, skipping:", ob.name)
|
||||
continue
|
||||
|
||||
pt_num = 0
|
||||
do_closed = (nu.flagU & 1)
|
||||
do_endpoints = (do_closed==0) and (nu.flagU & 2)
|
||||
do_closed = nu.use_cyclic_u
|
||||
do_endpoints = (do_closed == 0) and nu.use_endpoint_u
|
||||
|
||||
for pt in nu:
|
||||
pt = Vector(pt[0], pt[1], pt[2]) * ob_mat
|
||||
for pt in nu.points:
|
||||
pt = ob_mat * pt.co.copy().resize3D()
|
||||
file.write('v %.6f %.6f %.6f\n' % (pt[0], pt[1], pt[2]))
|
||||
pt_num += 1
|
||||
tot_verts += pt_num
|
||||
@ -247,7 +228,7 @@ def write_nurb(file, ob, ob_mat):
|
||||
pt_num += DEG_ORDER_U
|
||||
curve_ls = curve_ls + curve_ls[0:DEG_ORDER_U]
|
||||
|
||||
file.write('curv 0.0 1.0 %s\n' % (' '.join( [str(i) for i in curve_ls] ))) # Blender has no U and V values for the curve
|
||||
file.write('curv 0.0 1.0 %s\n' % (' '.join([str(i) for i in curve_ls]))) # Blender has no U and V values for the curve
|
||||
|
||||
# 'parm' keyword
|
||||
tot_parm = (DEG_ORDER_U + 1) + pt_num
|
||||
@ -334,7 +315,7 @@ def write_file(filepath, objects, scene,
|
||||
return ret
|
||||
|
||||
|
||||
print('OBJ Export path: "%s"' % filepath)
|
||||
print('OBJ Export path: %r' % filepath)
|
||||
temp_mesh_name = '~tmp-mesh'
|
||||
|
||||
time1 = time.clock()
|
||||
@ -344,13 +325,13 @@ def write_file(filepath, objects, scene,
|
||||
file = open(filepath, "w")
|
||||
|
||||
# Write Header
|
||||
file.write('# Blender v%s OBJ File: %s\n' % (bpy.app.version_string, bpy.data.filepath.split('/')[-1].split('\\')[-1] ))
|
||||
file.write('# Blender v%s OBJ File: %r\n' % (bpy.app.version_string, os.path.basename(bpy.data.filepath)))
|
||||
file.write('# www.blender.org\n')
|
||||
|
||||
# Tell the obj file what material file to use.
|
||||
if EXPORT_MTL:
|
||||
mtlfilepath = '%s.mtl' % '.'.join(filepath.split('.')[:-1])
|
||||
file.write('mtllib %s\n' % ( mtlfilepath.split('\\')[-1].split('/')[-1] ))
|
||||
mtlfilepath = os.path.splitext(filepath)[0] + ".mtl"
|
||||
file.write('mtllib %s\n' % repr(os.path.basename(mtlfilepath))[1:-1]) # filepath can contain non utf8 chars, use repr
|
||||
|
||||
if EXPORT_ROTX90:
|
||||
mat_xrot90= mathutils.Matrix.Rotation(-math.pi/2, 4, 'X')
|
||||
@ -390,16 +371,13 @@ def write_file(filepath, objects, scene,
|
||||
|
||||
for ob, ob_mat in obs:
|
||||
|
||||
# XXX postponed
|
||||
# # Nurbs curve support
|
||||
# if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob):
|
||||
# if EXPORT_ROTX90:
|
||||
# ob_mat = ob_mat * mat_xrot90
|
||||
|
||||
# totverts += write_nurb(file, ob, ob_mat)
|
||||
|
||||
# continue
|
||||
# end nurbs
|
||||
# Nurbs curve support
|
||||
if EXPORT_CURVE_AS_NURBS and test_nurbs_compat(ob):
|
||||
if EXPORT_ROTX90:
|
||||
ob_mat = ob_mat * mat_xrot90
|
||||
totverts += write_nurb(file, ob, ob_mat)
|
||||
continue
|
||||
# END NURBS
|
||||
|
||||
if ob.type != 'MESH':
|
||||
continue
|
||||
@ -418,7 +396,8 @@ def write_file(filepath, objects, scene,
|
||||
|
||||
if EXPORT_UV:
|
||||
faceuv = len(me.uv_textures) > 0
|
||||
uv_layer = me.active_uv_texture.data[:]
|
||||
if faceuv:
|
||||
uv_layer = me.uv_textures.active.data[:]
|
||||
else:
|
||||
faceuv = False
|
||||
|
||||
@ -542,7 +521,7 @@ def write_file(filepath, objects, scene,
|
||||
uv_face_mapping = [[0,0,0,0] for i in range(len(face_index_pairs))] # a bit of a waste for tri's :/
|
||||
|
||||
uv_dict = {} # could use a set() here
|
||||
uv_layer = me.active_uv_texture.data
|
||||
uv_layer = me.uv_textures.active.data
|
||||
for f, f_index in face_index_pairs:
|
||||
for uv_index, uv in enumerate(uv_layer[f_index].uv):
|
||||
uvkey = veckey2d(uv)
|
||||
@ -755,7 +734,8 @@ def write_file(filepath, objects, scene,
|
||||
|
||||
print("OBJ Export time: %.2f" % (time.clock() - time1))
|
||||
|
||||
def write(filepath, context,
|
||||
#
|
||||
def _write(context, filepath,
|
||||
EXPORT_TRI, # ok
|
||||
EXPORT_EDGES,
|
||||
EXPORT_NORMALS, # not yet
|
||||
@ -781,7 +761,7 @@ def write(filepath, context,
|
||||
orig_scene = context.scene
|
||||
|
||||
# Exit edit mode before exporting, so current object states are exported properly.
|
||||
if context.object:
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
# if EXPORT_ALL_SCENES:
|
||||
@ -852,105 +832,51 @@ def write(filepath, context,
|
||||
|
||||
'''
|
||||
Currently the exporter lacks these features:
|
||||
* nurbs
|
||||
* multiple scene export (only active scene is written)
|
||||
* particles
|
||||
'''
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class ExportOBJ(bpy.types.Operator):
|
||||
'''Save a Wavefront OBJ File'''
|
||||
def save(operator, context, filepath="",
|
||||
use_triangles=False,
|
||||
use_edges=False,
|
||||
use_normals=False,
|
||||
use_hq_normals=False,
|
||||
use_uvs=True,
|
||||
use_materials=True,
|
||||
copy_images=False,
|
||||
use_modifiers=True,
|
||||
use_rotate_x90=True,
|
||||
use_blen_objects=True,
|
||||
group_by_object=False,
|
||||
group_by_material=False,
|
||||
keep_vertex_order=False,
|
||||
use_vertex_groups=False,
|
||||
use_nurbs=True,
|
||||
use_selection=True,
|
||||
use_all_scenes=False,
|
||||
use_animation=False,
|
||||
):
|
||||
|
||||
bl_idname = "export.obj"
|
||||
bl_label = 'Export OBJ'
|
||||
_write(context, filepath,
|
||||
EXPORT_TRI=use_triangles,
|
||||
EXPORT_EDGES=use_edges,
|
||||
EXPORT_NORMALS=use_normals,
|
||||
EXPORT_NORMALS_HQ=use_hq_normals,
|
||||
EXPORT_UV=use_uvs,
|
||||
EXPORT_MTL=use_materials,
|
||||
EXPORT_COPY_IMAGES=copy_images,
|
||||
EXPORT_APPLY_MODIFIERS=use_modifiers,
|
||||
EXPORT_ROTX90=use_rotate_x90,
|
||||
EXPORT_BLEN_OBS=use_blen_objects,
|
||||
EXPORT_GROUP_BY_OB=group_by_object,
|
||||
EXPORT_GROUP_BY_MAT=group_by_material,
|
||||
EXPORT_KEEP_VERT_ORDER=keep_vertex_order,
|
||||
EXPORT_POLYGROUPS=use_vertex_groups,
|
||||
EXPORT_CURVE_AS_NURBS=use_nurbs,
|
||||
EXPORT_SEL_ONLY=use_selection,
|
||||
EXPORT_ALL_SCENES=use_all_scenes,
|
||||
EXPORT_ANIMATION=use_animation,
|
||||
)
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the OBJ file", maxlen= 1024, default= "")
|
||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
||||
|
||||
# context group
|
||||
use_selection = BoolProperty(name="Selection Only", description="Export selected objects only", default= False)
|
||||
use_all_scenes = BoolProperty(name="All Scenes", description="", default= False)
|
||||
use_animation = BoolProperty(name="Animation", description="", default= False)
|
||||
|
||||
# object group
|
||||
use_modifiers = BoolProperty(name="Apply Modifiers", description="Apply modifiers (preview resolution)", default= True)
|
||||
use_rotate90 = BoolProperty(name="Rotate X90", description="", default= True)
|
||||
|
||||
# extra data group
|
||||
use_edges = BoolProperty(name="Edges", description="", default= True)
|
||||
use_normals = BoolProperty(name="Normals", description="", default= False)
|
||||
use_hq_normals = BoolProperty(name="High Quality Normals", description="", default= True)
|
||||
use_uvs = BoolProperty(name="UVs", description="", default= True)
|
||||
use_materials = BoolProperty(name="Materials", description="", default= True)
|
||||
copy_images = BoolProperty(name="Copy Images", description="", default= False)
|
||||
use_triangles = BoolProperty(name="Triangulate", description="", default= False)
|
||||
use_vertex_groups = BoolProperty(name="Polygroups", description="", default= False)
|
||||
use_nurbs = BoolProperty(name="Nurbs", description="", default= False)
|
||||
|
||||
# grouping group
|
||||
use_blen_objects = BoolProperty(name="Objects as OBJ Objects", description="", default= True)
|
||||
group_by_object = BoolProperty(name="Objects as OBJ Groups ", description="", default= False)
|
||||
group_by_material = BoolProperty(name="Material Groups", description="", default= False)
|
||||
keep_vertex_order = BoolProperty(name="Keep Vertex Order", description="", default= False)
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
filepath = self.properties.filepath
|
||||
filepath = bpy.path.ensure_ext(filepath, ".obj")
|
||||
|
||||
write(filepath, context,
|
||||
EXPORT_TRI=self.properties.use_triangles,
|
||||
EXPORT_EDGES=self.properties.use_edges,
|
||||
EXPORT_NORMALS=self.properties.use_normals,
|
||||
EXPORT_NORMALS_HQ=self.properties.use_hq_normals,
|
||||
EXPORT_UV=self.properties.use_uvs,
|
||||
EXPORT_MTL=self.properties.use_materials,
|
||||
EXPORT_COPY_IMAGES=self.properties.copy_images,
|
||||
EXPORT_APPLY_MODIFIERS=self.properties.use_modifiers,
|
||||
EXPORT_ROTX90=self.properties.use_rotate90,
|
||||
EXPORT_BLEN_OBS=self.properties.use_blen_objects,
|
||||
EXPORT_GROUP_BY_OB=self.properties.group_by_object,
|
||||
EXPORT_GROUP_BY_MAT=self.properties.group_by_material,
|
||||
EXPORT_KEEP_VERT_ORDER=self.properties.keep_vertex_order,
|
||||
EXPORT_POLYGROUPS=self.properties.use_vertex_groups,
|
||||
EXPORT_CURVE_AS_NURBS=self.properties.use_nurbs,
|
||||
EXPORT_SEL_ONLY=self.properties.use_selection,
|
||||
EXPORT_ALL_SCENES=self.properties.use_all_scenes,
|
||||
EXPORT_ANIMATION=self.properties.use_animation)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
import os
|
||||
if not self.properties.is_property_set("filepath"):
|
||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".obj"
|
||||
|
||||
context.manager.add_fileselect(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(ExportOBJ.bl_idname, text="Wavefront (.obj)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
||||
|
||||
|
||||
# CONVERSION ISSUES
|
||||
# - matrix problem
|
||||
# - duplis - only tested dupliverts
|
||||
# - NURBS - needs API additions
|
||||
# - all scenes export
|
||||
# + normals calculation
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
return {'FINISHED'}
|
@ -18,85 +18,26 @@
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
__author__= "Campbell Barton", "Jiri Hnidek", "Paolo Ciccone"
|
||||
__url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org']
|
||||
__version__= "2.11"
|
||||
# Script copyright (C) Campbell Barton
|
||||
# Contributors: Campbell Barton, Jiri Hnidek, Paolo Ciccone
|
||||
|
||||
__bpydoc__= """\
|
||||
"""
|
||||
This script imports a Wavefront OBJ files to Blender.
|
||||
|
||||
Usage:
|
||||
Run this script from "File->Import" menu and then load the desired OBJ file.
|
||||
Note, This loads mesh objects and materials only, nurbs and curves are not supported.
|
||||
"""
|
||||
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# Script copyright (C) Campbell J Barton 2007
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENCE BLOCK *****
|
||||
# --------------------------------------------------------------------------
|
||||
http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
import bpy
|
||||
import mathutils
|
||||
from geometry import PolyFill
|
||||
from io_utils import load_image, unpack_list, unpack_face_list
|
||||
|
||||
# from Blender import Mesh, Draw, Window, Texture, Material, sys
|
||||
# # import BPyMesh
|
||||
# import BPyImage
|
||||
# import BPyMessages
|
||||
|
||||
# try: import os
|
||||
# except: os= False
|
||||
|
||||
def stripExt(name): # name is a string
|
||||
'''Strips the prefix off the name before writing'''
|
||||
index= name.rfind('.')
|
||||
if index != -1:
|
||||
return name[ : index ]
|
||||
else:
|
||||
return name
|
||||
# end path funcs
|
||||
|
||||
def unpack_list(list_of_tuples):
|
||||
l = []
|
||||
for t in list_of_tuples:
|
||||
l.extend(t)
|
||||
return l
|
||||
|
||||
# same as above except that it adds 0 for triangle faces
|
||||
def unpack_face_list(list_of_tuples):
|
||||
# allocate the entire list
|
||||
flat_ls = [0] * (len(list_of_tuples) * 4)
|
||||
i = 0
|
||||
|
||||
for t in list_of_tuples:
|
||||
if len(t) == 3:
|
||||
if t[2] == 0:
|
||||
t = t[1], t[2], t[0]
|
||||
else: # assuem quad
|
||||
if t[3] == 0 or t[2] == 0:
|
||||
t = t[2], t[3], t[0], t[1]
|
||||
|
||||
flat_ls[i:i + len(t)] = t
|
||||
i += 4
|
||||
return flat_ls
|
||||
|
||||
def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True):
|
||||
'''
|
||||
@ -116,7 +57,7 @@ def BPyMesh_ngon(from_data, indices, PREF_FIX_LOOPS= True):
|
||||
if not indices:
|
||||
return []
|
||||
|
||||
# return []
|
||||
# return []
|
||||
def rvec(co): return round(co.x, 6), round(co.y, 6), round(co.z, 6)
|
||||
def mlen(co): return abs(co[0])+abs(co[1])+abs(co[2]) # manhatten length of a vector, faster then length
|
||||
|
||||
@ -297,21 +238,6 @@ def line_value(line_split):
|
||||
elif length > 2:
|
||||
return ' '.join( line_split[1:] )
|
||||
|
||||
# limited replacement for BPyImage.comprehensiveImageLoad
|
||||
def load_image(imagepath, dirname):
|
||||
|
||||
if os.path.exists(imagepath):
|
||||
return bpy.data.images.load(imagepath)
|
||||
|
||||
variants = [imagepath, os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))]
|
||||
|
||||
for filepath in variants:
|
||||
for nfilepath in (filepath, bpy.path.resolve_ncase(filepath)):
|
||||
if os.path.exists(nfilepath):
|
||||
return bpy.data.images.load(nfilepath)
|
||||
|
||||
# TODO comprehensiveImageLoad also searched in bpy.config.textureDir
|
||||
return None
|
||||
|
||||
def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
|
||||
if '_' in imagepath:
|
||||
@ -327,21 +253,21 @@ def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
|
||||
return None
|
||||
|
||||
# def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
|
||||
# '''
|
||||
# Mainly uses comprehensiveImageLoad
|
||||
# but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores.
|
||||
# '''
|
||||
# '''
|
||||
# Mainly uses comprehensiveImageLoad
|
||||
# but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores.
|
||||
# '''
|
||||
|
||||
# if '_' in imagepath:
|
||||
# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
|
||||
# if image: return image
|
||||
# # Did the exporter rename the image?
|
||||
# image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
|
||||
# if image: return image
|
||||
# if '_' in imagepath:
|
||||
# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
|
||||
# if image: return image
|
||||
# # Did the exporter rename the image?
|
||||
# image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
|
||||
# if image: return image
|
||||
|
||||
# # Return an image, placeholder if it dosnt exist
|
||||
# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH)
|
||||
# return image
|
||||
# # Return an image, placeholder if it dosnt exist
|
||||
# image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH)
|
||||
# return image
|
||||
|
||||
|
||||
def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH):
|
||||
@ -356,18 +282,15 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
|
||||
#==================================================================================#
|
||||
def load_material_image(blender_material, context_material_name, imagepath, type):
|
||||
|
||||
texture= bpy.data.textures.new(type)
|
||||
texture.type= 'IMAGE'
|
||||
texture = texture.recast_type() # Workaround for limitation in rna api.
|
||||
# texture= bpy.data.textures.new(type)
|
||||
# texture.setType('Image')
|
||||
texture= bpy.data.textures.new(name=type, type='IMAGE')
|
||||
|
||||
# Absolute path - c:\.. etc would work here
|
||||
image= obj_image_load(imagepath, DIR, IMAGE_SEARCH)
|
||||
has_data = image.has_data if image else False
|
||||
image = obj_image_load(imagepath, DIR, IMAGE_SEARCH)
|
||||
has_data = False
|
||||
|
||||
if image:
|
||||
texture.image = image
|
||||
has_data = image.has_data
|
||||
|
||||
# Adds textures for materials (rendering)
|
||||
if type == 'Kd':
|
||||
@ -375,42 +298,65 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
|
||||
# Image has alpha
|
||||
|
||||
# XXX bitmask won't work?
|
||||
blender_material.add_texture(texture, 'UV', {'COLOR', 'ALPHA'})
|
||||
mtex = blender_material.texture_slots.add()
|
||||
mtex.texture = texture
|
||||
mtex.texture_coords = 'UV'
|
||||
mtex.use_map_color_diffuse = True
|
||||
mtex.use_map_alpha = True
|
||||
|
||||
texture.mipmap = True
|
||||
texture.interpolation = True
|
||||
texture.use_alpha = True
|
||||
blender_material.use_transparency = True
|
||||
blender_material.alpha = 0.0
|
||||
else:
|
||||
blender_material.add_texture(texture, 'UV', 'COLOR')
|
||||
mtex = blender_material.texture_slots.add()
|
||||
mtex.texture = texture
|
||||
mtex.texture_coords = 'UV'
|
||||
mtex.use_map_color_diffuse = True
|
||||
|
||||
# adds textures to faces (Textured/Alt-Z mode)
|
||||
# Only apply the diffuse texture to the face if the image has not been set with the inline usemat func.
|
||||
unique_material_images[context_material_name]= image, has_data # set the texface image
|
||||
|
||||
elif type == 'Ka':
|
||||
blender_material.add_texture(texture, 'UV', 'AMBIENT')
|
||||
# blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API
|
||||
mtex = blender_material.texture_slots.add()
|
||||
mtex.texture = texture
|
||||
mtex.texture_coords = 'UV'
|
||||
mtex.use_map_ambient = True
|
||||
# blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API
|
||||
|
||||
elif type == 'Ks':
|
||||
blender_material.add_texture(texture, 'UV', 'SPECULARITY')
|
||||
# blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC)
|
||||
mtex = blender_material.texture_slots.add()
|
||||
mtex.texture = texture
|
||||
mtex.texture_coords = 'UV'
|
||||
mtex.use_map_specular = True
|
||||
# blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC)
|
||||
|
||||
elif type == 'Bump':
|
||||
blender_material.add_texture(texture, 'UV', 'NORMAL')
|
||||
# blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR)
|
||||
mtex = blender_material.texture_slots.add()
|
||||
mtex.texture = texture
|
||||
mtex.texture_coords = 'UV'
|
||||
mtex.use_map_normal = True
|
||||
# blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR)
|
||||
elif type == 'D':
|
||||
blender_material.add_texture(texture, 'UV', 'ALPHA')
|
||||
mtex = blender_material.texture_slots.add()
|
||||
mtex.texture = texture
|
||||
mtex.texture_coords = 'UV'
|
||||
mtex.use_map_alpha = True
|
||||
blender_material.z_transparency = True
|
||||
blender_material.alpha = 0.0
|
||||
# blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA)
|
||||
# blender_material.mode |= Material.Modes.ZTRANSP
|
||||
# blender_material.alpha = 0.0
|
||||
# blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA)
|
||||
# blender_material.mode |= Material.Modes.ZTRANSP
|
||||
# blender_material.alpha = 0.0
|
||||
# Todo, unset deffuse material alpha if it has an alpha channel
|
||||
|
||||
elif type == 'refl':
|
||||
blender_material.add_texture(texture, 'UV', 'REFLECTION')
|
||||
# blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF)
|
||||
mtex = blender_material.texture_slots.add()
|
||||
mtex.texture = texture
|
||||
mtex.texture_coords = 'UV'
|
||||
mtex.use_map_reflect = True
|
||||
# blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF)
|
||||
|
||||
|
||||
# Add an MTL with the same name as the obj if no MTLs are spesified.
|
||||
@ -451,22 +397,16 @@ def create_materials(filepath, material_libs, unique_materials, unique_material_
|
||||
line_lower= line.lower().lstrip()
|
||||
if line_lower.startswith('ka'):
|
||||
context_material.mirror_color = (float(line_split[1]), float(line_split[2]), float(line_split[3]))
|
||||
# context_material.setMirCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
|
||||
elif line_lower.startswith('kd'):
|
||||
context_material.diffuse_color = (float(line_split[1]), float(line_split[2]), float(line_split[3]))
|
||||
# context_material.setRGBCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
|
||||
elif line_lower.startswith('ks'):
|
||||
context_material.specular_color = (float(line_split[1]), float(line_split[2]), float(line_split[3]))
|
||||
# context_material.setSpecCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
|
||||
elif line_lower.startswith('ns'):
|
||||
context_material.specular_hardness = int((float(line_split[1])*0.51))
|
||||
# context_material.setHardness( int((float(line_split[1])*0.51)) )
|
||||
elif line_lower.startswith('ni'): # Refraction index
|
||||
context_material.raytrace_transparency.ior = max(1, min(float(line_split[1]), 3))
|
||||
# context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3
|
||||
context_material.raytrace_transparency.ior = max(1, min(float(line_split[1]), 3)) # Between 1 and 3
|
||||
elif line_lower.startswith('d') or line_lower.startswith('tr'):
|
||||
context_material.alpha = float(line_split[1])
|
||||
# context_material.setAlpha(float(line_split[1]))
|
||||
elif line_lower.startswith('map_ka'):
|
||||
img_filepath= line_value(line.split())
|
||||
if img_filepath:
|
||||
@ -624,14 +564,14 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
|
||||
if has_ngons and len_face_vert_loc_indicies > 4:
|
||||
|
||||
ngon_face_indices= BPyMesh_ngon(verts_loc, face_vert_loc_indicies)
|
||||
faces.extend(\
|
||||
[(\
|
||||
[face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],\
|
||||
[face_vert_tex_indicies[ngon[0]], face_vert_tex_indicies[ngon[1]], face_vert_tex_indicies[ngon[2]] ],\
|
||||
context_material,\
|
||||
context_smooth_group,\
|
||||
context_object)\
|
||||
for ngon in ngon_face_indices]\
|
||||
faces.extend(
|
||||
[(
|
||||
[face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],
|
||||
[face_vert_tex_indicies[ngon[0]], face_vert_tex_indicies[ngon[1]], face_vert_tex_indicies[ngon[2]] ],
|
||||
context_material,
|
||||
context_smooth_group,
|
||||
context_object)
|
||||
for ngon in ngon_face_indices]
|
||||
)
|
||||
|
||||
# edges to make fgons
|
||||
@ -676,30 +616,25 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
|
||||
|
||||
# make sure the list isnt too big
|
||||
for material in materials:
|
||||
me.add_material(material)
|
||||
#me.vertices.extend([(0,0,0)]) # dummy vert
|
||||
me.materials.append(material)
|
||||
|
||||
me.add_geometry(len(verts_loc), 0, len(faces))
|
||||
me.vertices.add(len(verts_loc))
|
||||
me.faces.add(len(faces))
|
||||
|
||||
# verts_loc is a list of (x, y, z) tuples
|
||||
me.vertices.foreach_set("co", unpack_list(verts_loc))
|
||||
# me.vertices.extend(verts_loc)
|
||||
|
||||
# faces is a list of (vert_indices, texco_indices, ...) tuples
|
||||
# XXX faces should contain either 3 or 4 verts
|
||||
# XXX no check for valid face indices
|
||||
me.faces.foreach_set("vertices_raw", unpack_face_list([f[0] for f in faces]))
|
||||
# face_mapping= me.faces.extend([f[0] for f in faces], indexList=True)
|
||||
|
||||
if verts_tex and me.faces:
|
||||
me.add_uv_texture()
|
||||
# me.faceUV= 1
|
||||
# TEXMODE= Mesh.FaceModes['TEX']
|
||||
me.uv_textures.new()
|
||||
|
||||
context_material_old= -1 # avoid a dict lookup
|
||||
mat= 0 # rare case it may be un-initialized.
|
||||
me_faces= me.faces
|
||||
# ALPHA= Mesh.FaceTranspModes.ALPHA
|
||||
|
||||
for i, face in enumerate(faces):
|
||||
if len(face[0]) < 2:
|
||||
@ -708,14 +643,8 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
|
||||
if CREATE_EDGES:
|
||||
edges.append(face[0])
|
||||
else:
|
||||
# face_index_map= face_mapping[i]
|
||||
|
||||
# since we use foreach_set to add faces, all of them are added
|
||||
if 1:
|
||||
# if face_index_map!=None: # None means the face wasnt added
|
||||
|
||||
blender_face = me.faces[i]
|
||||
# blender_face= me_faces[face_index_map]
|
||||
|
||||
face_vert_loc_indicies,\
|
||||
face_vert_tex_indicies,\
|
||||
@ -734,7 +663,7 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
|
||||
context_material_old= context_material
|
||||
|
||||
blender_face.material_index= mat
|
||||
# blender_face.mat= mat
|
||||
# blender_face.mat= mat
|
||||
|
||||
|
||||
if verts_tex:
|
||||
@ -766,57 +695,57 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
|
||||
if len(face_vert_loc_indicies)==4:
|
||||
blender_tface.uv4= verts_tex[face_vert_tex_indicies[3]]
|
||||
|
||||
# for ii, uv in enumerate(blender_face.uv):
|
||||
# uv.x, uv.y= verts_tex[face_vert_tex_indicies[ii]]
|
||||
# for ii, uv in enumerate(blender_face.uv):
|
||||
# uv.x, uv.y= verts_tex[face_vert_tex_indicies[ii]]
|
||||
del me_faces
|
||||
# del ALPHA
|
||||
# del ALPHA
|
||||
|
||||
if CREATE_EDGES:
|
||||
|
||||
me.add_geometry(0, len(edges), 0)
|
||||
me.edges.add(len(edges))
|
||||
|
||||
# edges should be a list of (a, b) tuples
|
||||
me.edges.foreach_set("vertices", unpack_list(edges))
|
||||
# me_edges.extend( edges )
|
||||
# me_edges.extend( edges )
|
||||
|
||||
# del me_edges
|
||||
# del me_edges
|
||||
|
||||
# Add edge faces.
|
||||
# me_edges= me.edges
|
||||
# me_edges= me.edges
|
||||
|
||||
def edges_match(e1, e2):
|
||||
return (e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0])
|
||||
|
||||
# XXX slow
|
||||
# if CREATE_FGONS and fgon_edges:
|
||||
# for fgon_edge in fgon_edges.keys():
|
||||
# for ed in me.edges:
|
||||
# if edges_match(fgon_edge, ed.vertices):
|
||||
# ed.is_fgon = True
|
||||
# if CREATE_FGONS and fgon_edges:
|
||||
# for fgon_edge in fgon_edges.keys():
|
||||
# for ed in me.edges:
|
||||
# if edges_match(fgon_edge, ed.vertices):
|
||||
# ed.is_fgon = True
|
||||
|
||||
# if CREATE_FGONS and fgon_edges:
|
||||
# FGON= Mesh.EdgeFlags.FGON
|
||||
# for ed in me.findEdges( fgon_edges.keys() ):
|
||||
# if ed!=None:
|
||||
# me_edges[ed].flag |= FGON
|
||||
# del FGON
|
||||
# if CREATE_FGONS and fgon_edges:
|
||||
# FGON= Mesh.EdgeFlags.FGON
|
||||
# for ed in me.findEdges( fgon_edges.keys() ):
|
||||
# if ed!=None:
|
||||
# me_edges[ed].flag |= FGON
|
||||
# del FGON
|
||||
|
||||
# XXX slow
|
||||
# if unique_smooth_groups and sharp_edges:
|
||||
# for sharp_edge in sharp_edges.keys():
|
||||
# for ed in me.edges:
|
||||
# if edges_match(sharp_edge, ed.vertices):
|
||||
# ed.use_edge_sharp = True
|
||||
# if unique_smooth_groups and sharp_edges:
|
||||
# for sharp_edge in sharp_edges.keys():
|
||||
# for ed in me.edges:
|
||||
# if edges_match(sharp_edge, ed.vertices):
|
||||
# ed.use_edge_sharp = True
|
||||
|
||||
# if unique_smooth_groups and sharp_edges:
|
||||
# SHARP= Mesh.EdgeFlags.SHARP
|
||||
# for ed in me.findEdges( sharp_edges.keys() ):
|
||||
# if ed!=None:
|
||||
# me_edges[ed].flag |= SHARP
|
||||
# del SHARP
|
||||
# if unique_smooth_groups and sharp_edges:
|
||||
# SHARP= Mesh.EdgeFlags.SHARP
|
||||
# for ed in me.findEdges( sharp_edges.keys() ):
|
||||
# if ed!=None:
|
||||
# me_edges[ed].flag |= SHARP
|
||||
# del SHARP
|
||||
|
||||
me.update()
|
||||
# me.calcNormals()
|
||||
# me.calcNormals()
|
||||
|
||||
ob= bpy.data.objects.new("Mesh", me)
|
||||
new_objects.append(ob)
|
||||
@ -825,11 +754,8 @@ def create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, v
|
||||
# content of the vertex_groups. If the user selects to NOT have vertex groups saved then
|
||||
# the following test will never run
|
||||
for group_name, group_indicies in vertex_groups.items():
|
||||
group= ob.add_vertex_group(group_name)
|
||||
# me.addVertGroup(group_name)
|
||||
for vertex_index in group_indicies:
|
||||
ob.add_vertex_to_group(vertex_index, group, 1.0, 'REPLACE')
|
||||
# me.assignVertsToGroup(group_name, group_indicies, 1.00, Mesh.AssignModes.REPLACE)
|
||||
group= ob.vertex_groups.new(group_name)
|
||||
ob.vertex_groups.assign(group_indicies, group, 1.0, 'REPLACE')
|
||||
|
||||
|
||||
def create_nurbs(context_nurbs, vert_loc, new_objects):
|
||||
@ -857,21 +783,14 @@ def create_nurbs(context_nurbs, vert_loc, new_objects):
|
||||
print('\tWarning, surfaces not supported')
|
||||
return
|
||||
|
||||
cu = bpy.data.curves.new(name, 'Curve')
|
||||
cu.flag |= 1 # 3D curve
|
||||
cu = bpy.data.curves.new(name, 'CURVE')
|
||||
cu.dimensions = '3D'
|
||||
|
||||
nu = None
|
||||
for pt in curv_idx:
|
||||
nu = cu.splines.new('NURBS')
|
||||
nu.points.add(len(curv_idx) - 1) # a point is added to start with
|
||||
nu.points.foreach_set("co", [co_axis for vt_idx in curv_idx for co_axis in (vert_loc[vt_idx] + (1.0,))])
|
||||
|
||||
pt = vert_loc[pt]
|
||||
pt = (pt[0], pt[1], pt[2], 1.0)
|
||||
|
||||
if nu == None:
|
||||
nu = cu.appendNurb(pt)
|
||||
else:
|
||||
nu.append(pt)
|
||||
|
||||
nu.orderU = deg[0]+1
|
||||
nu.order_u = deg[0] + 1
|
||||
|
||||
# get for endpoint flag from the weighting
|
||||
if curv_range and len(parm_u) > deg[0]+1:
|
||||
@ -890,7 +809,7 @@ def create_nurbs(context_nurbs, vert_loc, new_objects):
|
||||
do_endpoints = False
|
||||
|
||||
if do_endpoints:
|
||||
nu.flagU |= 2
|
||||
nu.use_endpoint_u = True
|
||||
|
||||
|
||||
# close
|
||||
@ -905,10 +824,10 @@ def create_nurbs(context_nurbs, vert_loc, new_objects):
|
||||
break
|
||||
|
||||
if do_closed:
|
||||
nu.flagU |= 1
|
||||
nu.use_cyclic_u = True
|
||||
'''
|
||||
|
||||
ob= bpy.data.objects.new("Mesh", me)
|
||||
ob= bpy.data.objects.new("Nurb", cu)
|
||||
|
||||
new_objects.append(ob)
|
||||
|
||||
@ -927,7 +846,7 @@ def strip_slash(line_split):
|
||||
def get_float_func(filepath):
|
||||
'''
|
||||
find the float function for this obj file
|
||||
- weather to replace commas or not
|
||||
- whether to replace commas or not
|
||||
'''
|
||||
file= open(filepath, 'rU')
|
||||
for line in file: #.xreadlines():
|
||||
@ -941,31 +860,29 @@ def get_float_func(filepath):
|
||||
# incase all vert values were ints
|
||||
return float
|
||||
|
||||
def load_obj(filepath,
|
||||
context,
|
||||
CLAMP_SIZE= 0.0,
|
||||
CREATE_FGONS= True,
|
||||
CREATE_SMOOTH_GROUPS= True,
|
||||
CREATE_EDGES= True,
|
||||
SPLIT_OBJECTS= True,
|
||||
SPLIT_GROUPS= True,
|
||||
SPLIT_MATERIALS= True,
|
||||
ROTATE_X90= True,
|
||||
IMAGE_SEARCH=True,
|
||||
POLYGROUPS=False):
|
||||
def load(operator, context, filepath,
|
||||
CLAMP_SIZE= 0.0,
|
||||
CREATE_FGONS= True,
|
||||
CREATE_SMOOTH_GROUPS= True,
|
||||
CREATE_EDGES= True,
|
||||
SPLIT_OBJECTS= True,
|
||||
SPLIT_GROUPS= True,
|
||||
ROTATE_X90= True,
|
||||
IMAGE_SEARCH=True,
|
||||
POLYGROUPS=False):
|
||||
'''
|
||||
Called by the user interface or another script.
|
||||
load_obj(path) - should give acceptable results.
|
||||
This function passes the file and sends the data off
|
||||
to be split into objects and then converted into mesh objects
|
||||
'''
|
||||
print('\nimporting obj "%s"' % filepath)
|
||||
print('\nimporting obj %r' % filepath)
|
||||
|
||||
if SPLIT_OBJECTS or SPLIT_GROUPS or SPLIT_MATERIALS:
|
||||
if SPLIT_OBJECTS or SPLIT_GROUPS:
|
||||
POLYGROUPS = False
|
||||
|
||||
time_main= time.time()
|
||||
# time_main= sys.time()
|
||||
# time_main= sys.time()
|
||||
|
||||
verts_loc= []
|
||||
verts_tex= []
|
||||
@ -999,12 +916,12 @@ def load_obj(filepath,
|
||||
# when there are faces that end with \
|
||||
# it means they are multiline-
|
||||
# since we use xreadline we cant skip to the next line
|
||||
# so we need to know weather
|
||||
# so we need to know whether
|
||||
context_multi_line= ''
|
||||
|
||||
print('\tparsing obj file "%s"...' % filepath)
|
||||
print("\tparsing obj file...")
|
||||
time_sub= time.time()
|
||||
# time_sub= sys.time()
|
||||
# time_sub= sys.time()
|
||||
|
||||
file= open(filepath, 'rU')
|
||||
for line in file: #.xreadlines():
|
||||
@ -1055,7 +972,7 @@ def load_obj(filepath,
|
||||
vert_loc_index= int(obj_vert[0])-1
|
||||
# Add the vertex to the current group
|
||||
# *warning*, this wont work for files that have groups defined around verts
|
||||
if POLYGROUPS and context_vgroup:
|
||||
if POLYGROUPS and context_vgroup:
|
||||
vertex_groups[context_vgroup].append(vert_loc_index)
|
||||
|
||||
# Make relative negative vert indicies absolute
|
||||
@ -1147,8 +1064,7 @@ def load_obj(filepath,
|
||||
context_material= line_value(line.split())
|
||||
unique_materials[context_material]= None
|
||||
elif line.startswith('mtllib'): # usemap or usemat
|
||||
material_libs.extend( line.split()[1:] ) # can have multiple mtllib filenames per line
|
||||
|
||||
material_libs = list(set(material_libs) | set(line.split()[1:])) # can have multiple mtllib filenames per line, mtllib can appear more than once, so make sure only occurance of material exists
|
||||
|
||||
# Nurbs support
|
||||
elif line.startswith('cstype '):
|
||||
@ -1213,7 +1129,7 @@ def load_obj(filepath,
|
||||
|
||||
file.close()
|
||||
time_new= time.time()
|
||||
# time_new= sys.time()
|
||||
# time_new= sys.time()
|
||||
print('%.4f sec' % (time_new-time_sub))
|
||||
time_sub= time_new
|
||||
|
||||
@ -1222,7 +1138,7 @@ def load_obj(filepath,
|
||||
create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH)
|
||||
|
||||
time_new= time.time()
|
||||
# time_new= sys.time()
|
||||
# time_new= sys.time()
|
||||
print('%.4f sec' % (time_new-time_sub))
|
||||
time_sub= time_new
|
||||
|
||||
@ -1230,29 +1146,29 @@ def load_obj(filepath,
|
||||
verts_loc[:] = [(v[0], v[2], -v[1]) for v in verts_loc]
|
||||
|
||||
# deselect all
|
||||
# if context.selected_objects:
|
||||
# bpy.ops.OBJECT_OT_select_all()
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
scene = context.scene
|
||||
# scn.objects.selected = []
|
||||
# scn.objects.selected = []
|
||||
new_objects= [] # put new objects here
|
||||
|
||||
print('\tbuilding geometry...\n\tverts:%i faces:%i materials: %i smoothgroups:%i ...' % ( len(verts_loc), len(faces), len(unique_materials), len(unique_smooth_groups) ))
|
||||
# Split the mesh by objects/materials, may
|
||||
if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True
|
||||
else: SPLIT_OB_OR_GROUP = False
|
||||
if SPLIT_OBJECTS or SPLIT_GROUPS: SPLIT_OB_OR_GROUP = True
|
||||
else: SPLIT_OB_OR_GROUP = False
|
||||
|
||||
for verts_loc_split, faces_split, unique_materials_split, dataname in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
|
||||
# Create meshes from the data, warning 'vertex_groups' wont support splitting
|
||||
create_mesh(new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname)
|
||||
|
||||
# nurbs support
|
||||
# for context_nurbs in nurbs:
|
||||
# create_nurbs(scn, context_nurbs, verts_loc, new_objects)
|
||||
for context_nurbs in nurbs:
|
||||
create_nurbs(context_nurbs, verts_loc, new_objects)
|
||||
|
||||
# Create new obj
|
||||
for obj in new_objects:
|
||||
scene.objects.link(obj)
|
||||
base = scene.objects.link(obj)
|
||||
base.select = True
|
||||
|
||||
scene.update()
|
||||
|
||||
@ -1260,340 +1176,45 @@ def load_obj(filepath,
|
||||
axis_min= [ 1000000000]*3
|
||||
axis_max= [-1000000000]*3
|
||||
|
||||
# if CLAMP_SIZE:
|
||||
# # Get all object bounds
|
||||
# for ob in new_objects:
|
||||
# for v in ob.getBoundBox():
|
||||
# for axis, value in enumerate(v):
|
||||
# if axis_min[axis] > value: axis_min[axis]= value
|
||||
# if axis_max[axis] < value: axis_max[axis]= value
|
||||
# if CLAMP_SIZE:
|
||||
# # Get all object bounds
|
||||
# for ob in new_objects:
|
||||
# for v in ob.getBoundBox():
|
||||
# for axis, value in enumerate(v):
|
||||
# if axis_min[axis] > value: axis_min[axis]= value
|
||||
# if axis_max[axis] < value: axis_max[axis]= value
|
||||
|
||||
# # Scale objects
|
||||
# max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2])
|
||||
# scale= 1.0
|
||||
# # Scale objects
|
||||
# max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1], axis_max[2]-axis_min[2])
|
||||
# scale= 1.0
|
||||
|
||||
# while CLAMP_SIZE < max_axis * scale:
|
||||
# scale= scale/10.0
|
||||
# while CLAMP_SIZE < max_axis * scale:
|
||||
# scale= scale/10.0
|
||||
|
||||
# for ob in new_objects:
|
||||
# ob.setSize(scale, scale, scale)
|
||||
# for ob in new_objects:
|
||||
# ob.setSize(scale, scale, scale)
|
||||
|
||||
# Better rotate the vert locations
|
||||
#if not ROTATE_X90:
|
||||
# for ob in new_objects:
|
||||
# ob.RotX = -1.570796326794896558
|
||||
# for ob in new_objects:
|
||||
# ob.RotX = -1.570796326794896558
|
||||
|
||||
time_new= time.time()
|
||||
# time_new= sys.time()
|
||||
# time_new= sys.time()
|
||||
|
||||
print('%.4f sec' % (time_new-time_sub))
|
||||
print('finished importing: "%s" in %.4f sec.' % (filepath, (time_new-time_main)))
|
||||
|
||||
|
||||
DEBUG= True
|
||||
|
||||
|
||||
def load_obj_ui(filepath, BATCH_LOAD= False):
|
||||
if BPyMessages.Error_NoFile(filepath):
|
||||
return
|
||||
|
||||
global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90
|
||||
|
||||
CREATE_SMOOTH_GROUPS= Draw.Create(0)
|
||||
CREATE_FGONS= Draw.Create(1)
|
||||
CREATE_EDGES= Draw.Create(1)
|
||||
SPLIT_OBJECTS= Draw.Create(0)
|
||||
SPLIT_GROUPS= Draw.Create(0)
|
||||
CLAMP_SIZE= Draw.Create(10.0)
|
||||
IMAGE_SEARCH= Draw.Create(1)
|
||||
POLYGROUPS= Draw.Create(0)
|
||||
KEEP_VERT_ORDER= Draw.Create(1)
|
||||
ROTATE_X90= Draw.Create(1)
|
||||
|
||||
|
||||
# Get USER Options
|
||||
# Note, Works but not pretty, instead use a more complicated GUI
|
||||
'''
|
||||
pup_block= [\
|
||||
'Import...',\
|
||||
('Smooth Groups', CREATE_SMOOTH_GROUPS, 'Surround smooth groups by sharp edges'),\
|
||||
('Create FGons', CREATE_FGONS, 'Import faces with more then 4 verts as fgons.'),\
|
||||
('Lines', CREATE_EDGES, 'Import lines and faces with 2 verts as edges'),\
|
||||
'Separate objects from obj...',\
|
||||
('Object', SPLIT_OBJECTS, 'Import OBJ Objects into Blender Objects'),\
|
||||
('Group', SPLIT_GROUPS, 'Import OBJ Groups into Blender Objects'),\
|
||||
'Options...',\
|
||||
('Keep Vert Order', KEEP_VERT_ORDER, 'Keep vert and face order, disables some other options.'),\
|
||||
('Clamp Scale:', CLAMP_SIZE, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)'),\
|
||||
('Image Search', IMAGE_SEARCH, 'Search subdirs for any assosiated images (Warning, may be slow)'),\
|
||||
]
|
||||
|
||||
if not Draw.PupBlock('Import OBJ...', pup_block):
|
||||
return
|
||||
|
||||
if KEEP_VERT_ORDER.val:
|
||||
SPLIT_OBJECTS.val = False
|
||||
SPLIT_GROUPS.val = False
|
||||
'''
|
||||
|
||||
|
||||
|
||||
# BEGIN ALTERNATIVE UI *******************
|
||||
if True:
|
||||
|
||||
EVENT_NONE = 0
|
||||
EVENT_EXIT = 1
|
||||
EVENT_REDRAW = 2
|
||||
EVENT_IMPORT = 3
|
||||
|
||||
GLOBALS = {}
|
||||
GLOBALS['EVENT'] = EVENT_REDRAW
|
||||
#GLOBALS['MOUSE'] = Window.GetMouseCoords()
|
||||
GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()]
|
||||
|
||||
def obj_ui_set_event(e,v):
|
||||
GLOBALS['EVENT'] = e
|
||||
|
||||
def do_split(e,v):
|
||||
global SPLIT_OBJECTS, SPLIT_GROUPS, KEEP_VERT_ORDER, POLYGROUPS
|
||||
if SPLIT_OBJECTS.val or SPLIT_GROUPS.val:
|
||||
KEEP_VERT_ORDER.val = 0
|
||||
POLYGROUPS.val = 0
|
||||
else:
|
||||
KEEP_VERT_ORDER.val = 1
|
||||
|
||||
def do_vertorder(e,v):
|
||||
global SPLIT_OBJECTS, SPLIT_GROUPS, KEEP_VERT_ORDER
|
||||
if KEEP_VERT_ORDER.val:
|
||||
SPLIT_OBJECTS.val = SPLIT_GROUPS.val = 0
|
||||
else:
|
||||
if not (SPLIT_OBJECTS.val or SPLIT_GROUPS.val):
|
||||
KEEP_VERT_ORDER.val = 1
|
||||
|
||||
def do_polygroups(e,v):
|
||||
global SPLIT_OBJECTS, SPLIT_GROUPS, KEEP_VERT_ORDER, POLYGROUPS
|
||||
if POLYGROUPS.val:
|
||||
SPLIT_OBJECTS.val = SPLIT_GROUPS.val = 0
|
||||
|
||||
def do_help(e,v):
|
||||
url = __url__[0]
|
||||
print('Trying to open web browser with documentation at this address...')
|
||||
print('\t' + url)
|
||||
|
||||
try:
|
||||
import webbrowser
|
||||
webbrowser.open(url)
|
||||
except:
|
||||
print('...could not open a browser window.')
|
||||
|
||||
def obj_ui():
|
||||
ui_x, ui_y = GLOBALS['MOUSE']
|
||||
|
||||
# Center based on overall pup size
|
||||
ui_x -= 165
|
||||
ui_y -= 90
|
||||
|
||||
global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, CLAMP_SIZE, IMAGE_SEARCH, POLYGROUPS, KEEP_VERT_ORDER, ROTATE_X90
|
||||
|
||||
Draw.Label('Import...', ui_x+9, ui_y+159, 220, 21)
|
||||
Draw.BeginAlign()
|
||||
CREATE_SMOOTH_GROUPS = Draw.Toggle('Smooth Groups', EVENT_NONE, ui_x+9, ui_y+139, 110, 20, CREATE_SMOOTH_GROUPS.val, 'Surround smooth groups by sharp edges')
|
||||
CREATE_FGONS = Draw.Toggle('NGons as FGons', EVENT_NONE, ui_x+119, ui_y+139, 110, 20, CREATE_FGONS.val, 'Import faces with more then 4 verts as fgons')
|
||||
CREATE_EDGES = Draw.Toggle('Lines as Edges', EVENT_NONE, ui_x+229, ui_y+139, 110, 20, CREATE_EDGES.val, 'Import lines and faces with 2 verts as edges')
|
||||
Draw.EndAlign()
|
||||
|
||||
Draw.Label('Separate objects by OBJ...', ui_x+9, ui_y+110, 220, 20)
|
||||
Draw.BeginAlign()
|
||||
SPLIT_OBJECTS = Draw.Toggle('Object', EVENT_REDRAW, ui_x+9, ui_y+89, 55, 21, SPLIT_OBJECTS.val, 'Import OBJ Objects into Blender Objects', do_split)
|
||||
SPLIT_GROUPS = Draw.Toggle('Group', EVENT_REDRAW, ui_x+64, ui_y+89, 55, 21, SPLIT_GROUPS.val, 'Import OBJ Groups into Blender Objects', do_split)
|
||||
Draw.EndAlign()
|
||||
|
||||
# Only used for user feedback
|
||||
KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+184, ui_y+89, 113, 21, KEEP_VERT_ORDER.val, 'Keep vert and face order, disables split options, enable for morph targets', do_vertorder)
|
||||
|
||||
ROTATE_X90 = Draw.Toggle('-X90', EVENT_REDRAW, ui_x+302, ui_y+89, 38, 21, ROTATE_X90.val, 'Rotate X 90.')
|
||||
|
||||
Draw.Label('Options...', ui_x+9, ui_y+60, 211, 20)
|
||||
CLAMP_SIZE = Draw.Number('Clamp Scale: ', EVENT_NONE, ui_x+9, ui_y+39, 130, 21, CLAMP_SIZE.val, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)')
|
||||
POLYGROUPS = Draw.Toggle('Poly Groups', EVENT_REDRAW, ui_x+144, ui_y+39, 90, 21, POLYGROUPS.val, 'Import OBJ groups as vertex groups.', do_polygroups)
|
||||
IMAGE_SEARCH = Draw.Toggle('Image Search', EVENT_NONE, ui_x+239, ui_y+39, 100, 21, IMAGE_SEARCH.val, 'Search subdirs for any assosiated images (Warning, may be slow)')
|
||||
Draw.BeginAlign()
|
||||
Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 21, 'Load the wiki page for this script', do_help)
|
||||
Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 21, '', obj_ui_set_event)
|
||||
Draw.PushButton('Import', EVENT_IMPORT, ui_x+229, ui_y+9, 110, 21, 'Import with these settings', obj_ui_set_event)
|
||||
Draw.EndAlign()
|
||||
|
||||
|
||||
# hack so the toggle buttons redraw. this is not nice at all
|
||||
while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_IMPORT):
|
||||
Draw.UIBlock(obj_ui, 0)
|
||||
|
||||
if GLOBALS['EVENT'] != EVENT_IMPORT:
|
||||
return
|
||||
|
||||
# END ALTERNATIVE UI *********************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Window.WaitCursor(1)
|
||||
|
||||
if BATCH_LOAD: # load the dir
|
||||
try:
|
||||
files= [ f for f in os.listdir(filepath) if f.lower().endswith('.obj') ]
|
||||
except:
|
||||
Window.WaitCursor(0)
|
||||
Draw.PupMenu('Error%t|Could not open path ' + filepath)
|
||||
return
|
||||
|
||||
if not files:
|
||||
Window.WaitCursor(0)
|
||||
Draw.PupMenu('Error%t|No files at path ' + filepath)
|
||||
return
|
||||
|
||||
for f in files:
|
||||
scn= bpy.data.scenes.new( stripExt(f) )
|
||||
scn.makeCurrent()
|
||||
|
||||
load_obj(sys.join(filepath, f),\
|
||||
CLAMP_SIZE.val,\
|
||||
CREATE_FGONS.val,\
|
||||
CREATE_SMOOTH_GROUPS.val,\
|
||||
CREATE_EDGES.val,\
|
||||
SPLIT_OBJECTS.val,\
|
||||
SPLIT_GROUPS.val,\
|
||||
ROTATE_X90.val,\
|
||||
IMAGE_SEARCH.val,\
|
||||
POLYGROUPS.val
|
||||
)
|
||||
|
||||
else: # Normal load
|
||||
load_obj(filepath,\
|
||||
CLAMP_SIZE.val,\
|
||||
CREATE_FGONS.val,\
|
||||
CREATE_SMOOTH_GROUPS.val,\
|
||||
CREATE_EDGES.val,\
|
||||
SPLIT_OBJECTS.val,\
|
||||
SPLIT_GROUPS.val,\
|
||||
ROTATE_X90.val,\
|
||||
IMAGE_SEARCH.val,\
|
||||
POLYGROUPS.val
|
||||
)
|
||||
|
||||
Window.WaitCursor(0)
|
||||
|
||||
|
||||
def load_obj_ui_batch(file):
|
||||
load_obj_ui(file, True)
|
||||
|
||||
DEBUG= False
|
||||
|
||||
# if __name__=='__main__' and not DEBUG:
|
||||
# if os and Window.GetKeyQualifiers() & Window.Qual.SHIFT:
|
||||
# Window.FileSelector(load_obj_ui_batch, 'Import OBJ Dir', '')
|
||||
# else:
|
||||
# Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj')
|
||||
|
||||
# For testing compatibility
|
||||
'''
|
||||
else:
|
||||
# DEBUG ONLY
|
||||
TIME= sys.time()
|
||||
DIR = '/fe/obj'
|
||||
import os
|
||||
print 'Searching for files'
|
||||
def fileList(path):
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
for filename in filenames:
|
||||
yield os.path.join(dirpath, filename)
|
||||
|
||||
files = [f for f in fileList(DIR) if f.lower().endswith('.obj')]
|
||||
files.sort()
|
||||
|
||||
for i, obj_file in enumerate(files):
|
||||
if 0 < i < 20:
|
||||
print 'Importing', obj_file, '\nNUMBER', i, 'of', len(files)
|
||||
newScn= bpy.data.scenes.new(os.path.basename(obj_file))
|
||||
newScn.makeCurrent()
|
||||
load_obj(obj_file, False, IMAGE_SEARCH=0)
|
||||
|
||||
print 'TOTAL TIME: %.6f' % (sys.time() - TIME)
|
||||
'''
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class IMPORT_OT_obj(bpy.types.Operator):
|
||||
'''Load a Wavefront OBJ File'''
|
||||
bl_idname = "import_scene.obj"
|
||||
bl_label = "Import OBJ"
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
|
||||
|
||||
filepath = StringProperty(name="File Path", description="Filepath used for importing the OBJ file", maxlen= 1024, default= "")
|
||||
|
||||
CREATE_SMOOTH_GROUPS = BoolProperty(name="Smooth Groups", description="Surround smooth groups by sharp edges", default= True)
|
||||
CREATE_FGONS = BoolProperty(name="NGons as FGons", description="Import faces with more then 4 verts as fgons", default= True)
|
||||
CREATE_EDGES = BoolProperty(name="Lines as Edges", description="Import lines and faces with 2 verts as edge", default= True)
|
||||
SPLIT_OBJECTS = BoolProperty(name="Object", description="Import OBJ Objects into Blender Objects", default= True)
|
||||
SPLIT_GROUPS = BoolProperty(name="Group", description="Import OBJ Groups into Blender Objects", default= True)
|
||||
# old comment: only used for user feedback
|
||||
# disabled this option because in old code a handler for it disabled SPLIT* params, it's not passed to load_obj
|
||||
# KEEP_VERT_ORDER = BoolProperty(name="Keep Vert Order", description="Keep vert and face order, disables split options, enable for morph targets", default= True)
|
||||
ROTATE_X90 = BoolProperty(name="-X90", description="Rotate X 90.", default= True)
|
||||
CLAMP_SIZE = FloatProperty(name="Clamp Scale", description="Clamp the size to this maximum (Zero to Disable)", min=0.0, max=1000.0, soft_min=0.0, soft_max=1000.0, default=0.0)
|
||||
POLYGROUPS = BoolProperty(name="Poly Groups", description="Import OBJ groups as vertex groups.", default= True)
|
||||
IMAGE_SEARCH = BoolProperty(name="Image Search", description="Search subdirs for any assosiated images (Warning, may be slow)", default= True)
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
# print("Selected: " + context.active_object.name)
|
||||
|
||||
load_obj(self.properties.filepath,
|
||||
context,
|
||||
self.properties.CLAMP_SIZE,
|
||||
self.properties.CREATE_FGONS,
|
||||
self.properties.CREATE_SMOOTH_GROUPS,
|
||||
self.properties.CREATE_EDGES,
|
||||
self.properties.SPLIT_OBJECTS,
|
||||
self.properties.SPLIT_GROUPS,
|
||||
self.properties.ROTATE_X90,
|
||||
self.properties.IMAGE_SEARCH,
|
||||
self.properties.POLYGROUPS)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
context.manager.add_fileselect(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(IMPORT_OT_obj.bl_idname, text="Wavefront (.obj)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_import.append(menu_func)
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_import.remove(menu_func)
|
||||
print('finished importing: %r in %.4f sec.' % (filepath, (time_new-time_main)))
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
# NOTES (all line numbers refer to 2.4x import_obj.py, not this file)
|
||||
# check later: line 489
|
||||
# can convert now: edge flags, edges: lines 508-528
|
||||
# ngon (uses python module BPyMesh): 384-414
|
||||
# nurbs: 947-
|
||||
# NEXT clamp size: get bound box with RNA
|
||||
# get back to l 140 (here)
|
||||
# search image in bpy.config.textureDir - load_image
|
||||
# replaced BPyImage.comprehensiveImageLoad with a simplified version that only checks additional directory specified, but doesn't search dirs recursively (obj_image_load)
|
||||
# bitmask won't work? - 132
|
||||
# uses operator bpy.ops.OBJECT_OT_select_all() to deselect all (not necessary?)
|
||||
# uses bpy.sys.time()
|
||||
|
||||
if __name__ == "__main__":
|
61
release/scripts/op/io_scene_x3d/__init__.py
Normal file
61
release/scripts/op/io_scene_x3d/__init__.py
Normal file
@ -0,0 +1,61 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||
if "bpy" in locals():
|
||||
# only reload if we alredy loaded, highly annoying
|
||||
import sys
|
||||
reload(sys.modules.get("io_scene_x3d.export_x3d", sys))
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy.props import *
|
||||
from io_utils import ExportHelper
|
||||
|
||||
|
||||
class ExportX3D(bpy.types.Operator, ExportHelper):
|
||||
'''Export selection to Extensible 3D file (.x3d)'''
|
||||
bl_idname = "export_scene.x3d"
|
||||
bl_label = 'Export X3D'
|
||||
|
||||
filename_ext = ".x3d"
|
||||
|
||||
use_apply_modifiers = BoolProperty(name="Apply Modifiers", description="Use transformed mesh data from each object", default=True)
|
||||
use_triangulate = BoolProperty(name="Triangulate", description="Triangulate quads.", default=False)
|
||||
use_compress = BoolProperty(name="Compress", description="GZip the resulting file, requires a full python install", default=False)
|
||||
|
||||
def execute(self, context):
|
||||
import io_scene_x3d.export_x3d
|
||||
return io_scene_x3d.export_x3d.save(self, context, **self.properties)
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(ExportX3D.bl_idname, text="X3D Extensible 3D (.x3d)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
||||
|
||||
# NOTES
|
||||
# - blender version is hardcoded
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
@ -18,68 +18,29 @@
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
__author__ = ("Bart", "Campbell Barton")
|
||||
__email__ = ["Bart, bart:neeneenee*de"]
|
||||
__url__ = ["Author's (Bart) homepage, http://www.neeneenee.de/vrml"]
|
||||
__version__ = "2006/01/17"
|
||||
__bpydoc__ = """\
|
||||
# Contributors: bart:neeneenee*de, http://www.neeneenee.de/vrml, Campbell Barton
|
||||
|
||||
"""
|
||||
This script exports to X3D format.
|
||||
|
||||
Usage:
|
||||
|
||||
Run this script from "File->Export" menu. A pop-up will ask whether you
|
||||
want to export only selected or all relevant objects.
|
||||
|
||||
Known issues:<br>
|
||||
Known issues:
|
||||
Doesn't handle multiple materials (don't use material indices);<br>
|
||||
Doesn't handle multiple UV textures on a single mesh (create a mesh for each texture);<br>
|
||||
Can't get the texture array associated with material * not the UV ones;
|
||||
"""
|
||||
|
||||
|
||||
# $Id$
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
# X3D exporter for blender 2.36 or above
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ***** END GPL LICENCE BLOCK *****
|
||||
#
|
||||
|
||||
####################################
|
||||
# Library dependancies
|
||||
####################################
|
||||
|
||||
import math
|
||||
import os
|
||||
|
||||
import bpy
|
||||
import mathutils
|
||||
|
||||
from export_3ds import create_derived_objects, free_derived_objects
|
||||
from io_utils import create_derived_objects, free_derived_objects
|
||||
|
||||
# import Blender
|
||||
# from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh
|
||||
# from Blender.Scene import Render
|
||||
# import BPyObject
|
||||
# import BPyMesh
|
||||
|
||||
#
|
||||
DEG2RAD=0.017453292519943295
|
||||
MATWORLD= mathutils.Matrix.Rotation(-90, 4, 'X')
|
||||
|
||||
@ -87,8 +48,7 @@ MATWORLD= mathutils.Matrix.Rotation(-90, 4, 'X')
|
||||
# Global Variables
|
||||
####################################
|
||||
|
||||
filename = ""
|
||||
# filename = Blender.Get('filename')
|
||||
filepath = ""
|
||||
_safeOverwrite = True
|
||||
|
||||
extension = ''
|
||||
@ -99,7 +59,7 @@ extension = ''
|
||||
|
||||
class x3d_class:
|
||||
|
||||
def __init__(self, filename):
|
||||
def __init__(self, filepath):
|
||||
#--- public you can change these ---
|
||||
self.writingcolor = 0
|
||||
self.writingtexture = 0
|
||||
@ -122,18 +82,18 @@ class x3d_class:
|
||||
self.matNames={} # dictionary of materiaNames
|
||||
self.meshNames={} # dictionary of meshNames
|
||||
self.indentLevel=0 # keeps track of current indenting
|
||||
self.filename=filename
|
||||
self.filepath=filepath
|
||||
self.file = None
|
||||
if filename.lower().endswith('.x3dz'):
|
||||
if filepath.lower().endswith('.x3dz'):
|
||||
try:
|
||||
import gzip
|
||||
self.file = gzip.open(filename, "w")
|
||||
self.file = gzip.open(filepath, "w")
|
||||
except:
|
||||
print("failed to import compression modules, exporting uncompressed")
|
||||
self.filename = filename[:-1] # remove trailing z
|
||||
self.filepath = filepath[:-1] # remove trailing z
|
||||
|
||||
if self.file == None:
|
||||
self.file = open(self.filename, "w")
|
||||
self.file = open(self.filepath, "w")
|
||||
|
||||
self.bNav=0
|
||||
self.nodeID=0
|
||||
@ -175,15 +135,15 @@ class x3d_class:
|
||||
##########################################################
|
||||
|
||||
def writeHeader(self):
|
||||
#bfile = sys.expandpath( Blender.Get('filename') ).replace('<', '<').replace('>', '>')
|
||||
bfile = self.filename.replace('<', '<').replace('>', '>') # use outfile name
|
||||
#bfile = sys.expandpath( Blender.Get('filepath') ).replace('<', '<').replace('>', '>')
|
||||
bfile = repr(os.path.basename(self.filepath).replace('<', '<').replace('>', '>'))[1:-1] # use outfile name
|
||||
self.file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
|
||||
self.file.write("<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.0//EN\" \"http://www.web3d.org/specifications/x3d-3.0.dtd\">\n")
|
||||
self.file.write("<X3D version=\"3.0\" profile=\"Immersive\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema-instance\" xsd:noNamespaceSchemaLocation=\"http://www.web3d.org/specifications/x3d-3.0.xsd\">\n")
|
||||
self.file.write("<head>\n")
|
||||
self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % os.path.basename(bfile))
|
||||
self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % bfile)
|
||||
# self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % sys.basename(bfile))
|
||||
self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % '2.5')
|
||||
self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % bpy.app.version_string)
|
||||
# self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % Blender.Get('version'))
|
||||
self.file.write("\t<meta name=\"translator\" content=\"X3D exporter v1.55 (2006/01/17)\" />\n")
|
||||
self.file.write("</head>\n")
|
||||
@ -258,12 +218,9 @@ class x3d_class:
|
||||
|
||||
def writeFog(self, world):
|
||||
if world:
|
||||
mtype = world.mist.falloff
|
||||
# mtype = world.getMistype()
|
||||
mparam = world.mist
|
||||
# mparam = world.getMist()
|
||||
mtype = world.mist_settings.falloff
|
||||
mparam = world.mist_settings
|
||||
grd = world.horizon_color
|
||||
# grd = world.getHor()
|
||||
grd0, grd1, grd2 = grd[0], grd[1], grd[2]
|
||||
else:
|
||||
return
|
||||
@ -277,7 +234,7 @@ class x3d_class:
|
||||
return
|
||||
|
||||
def writeNavigationInfo(self, scene):
|
||||
self.file.write('<NavigationInfo headlight="FALSE" visibilityLimit="0.0" type=\'"EXAMINE","ANY"\' avatarSize="0.25, 1.75, 0.75" />\n')
|
||||
self.file.write('<NavigationInfo headlight="false" visibilityLimit="0.0" type=\'"EXAMINE","ANY"\' avatarSize="0.25, 1.75, 0.75" />\n')
|
||||
|
||||
def writeSpotLight(self, ob, mtx, lamp, world):
|
||||
safeName = self.cleanStr(ob.name)
|
||||
@ -402,9 +359,9 @@ class x3d_class:
|
||||
if len(mesh.faces) == 0: return
|
||||
mode = []
|
||||
# mode = 0
|
||||
if mesh.active_uv_texture:
|
||||
if mesh.uv_textures.active:
|
||||
# if mesh.faceUV:
|
||||
for face in mesh.active_uv_texture.data:
|
||||
for face in mesh.uv_textures.active.data:
|
||||
# for face in mesh.faces:
|
||||
if face.use_halo and 'HALO' not in mode:
|
||||
mode += ['HALO']
|
||||
@ -460,40 +417,39 @@ class x3d_class:
|
||||
|
||||
self.writeIndented("<Shape>\n",1)
|
||||
maters=mesh.materials
|
||||
hasImageTexture=0
|
||||
hasImageTexture = False
|
||||
is_smooth = False
|
||||
|
||||
if len(maters) > 0 or mesh.active_uv_texture:
|
||||
if len(maters) > 0 or mesh.uv_textures.active:
|
||||
# if len(maters) > 0 or mesh.faceUV:
|
||||
self.writeIndented("<Appearance>\n", 1)
|
||||
# right now this script can only handle a single material per mesh.
|
||||
if len(maters) >= 1:
|
||||
mat=maters[0]
|
||||
# matFlags = mat.getMode()
|
||||
if not mat.use_face_texture:
|
||||
# if not matFlags & Blender.Material.Modes['TEXFACE']:
|
||||
self.writeMaterial(mat, self.cleanStr(mat.name,''), world)
|
||||
# self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world)
|
||||
if len(maters) > 1:
|
||||
print("Warning: mesh named %s has multiple materials" % meshName)
|
||||
print("Warning: only one material per object handled")
|
||||
if len(maters) >= 1 and maters[0].use_face_texture == False:
|
||||
mat = maters[0]
|
||||
self.writeMaterial(mat, self.cleanStr(mat.name,''), world)
|
||||
if len(maters) > 1:
|
||||
print("Warning: mesh named %s has multiple materials" % meshName)
|
||||
print("Warning: only one material per object handled")
|
||||
|
||||
if not len(maters) or maters[0].use_face_texture:
|
||||
#-- textures
|
||||
face = None
|
||||
if mesh.active_uv_texture:
|
||||
# if mesh.faceUV:
|
||||
for face in mesh.active_uv_texture.data:
|
||||
# for face in mesh.faces:
|
||||
if face.image:
|
||||
# if (hasImageTexture == 0) and (face.image):
|
||||
self.writeImageTexture(face.image)
|
||||
# hasImageTexture=1 # keep track of face texture
|
||||
break
|
||||
if self.tilenode == 1 and face and face.image:
|
||||
# if self.tilenode == 1:
|
||||
self.writeIndented("<TextureTransform scale=\"%s %s\" />\n" % (face.image.xrep, face.image.yrep))
|
||||
self.tilenode = 0
|
||||
self.writeIndented("</Appearance>\n", -1)
|
||||
image = None
|
||||
if mesh.uv_textures.active:
|
||||
for face in mesh.uv_textures.active.data:
|
||||
if face.use_image:
|
||||
image = face.image
|
||||
if image:
|
||||
self.writeImageTexture(image)
|
||||
break
|
||||
|
||||
if image:
|
||||
hasImageTexture = True
|
||||
|
||||
if self.tilenode == 1:
|
||||
self.writeIndented("<TextureTransform scale=\"%s %s\" />\n" % (image.xrep, image.yrep))
|
||||
self.tilenode = 0
|
||||
|
||||
self.writeIndented("</Appearance>\n", -1)
|
||||
|
||||
#-- IndexedFaceSet or IndexedLineSet
|
||||
|
||||
@ -525,11 +481,10 @@ class x3d_class:
|
||||
self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp)))
|
||||
|
||||
#--- output textureCoordinates if UV texture used
|
||||
if mesh.active_uv_texture:
|
||||
# if mesh.faceUV:
|
||||
if mesh.uv_textures.active:
|
||||
if self.matonly == 1 and self.share == 1:
|
||||
self.writeFaceColors(mesh)
|
||||
elif hasImageTexture == 1:
|
||||
elif hasImageTexture == True:
|
||||
self.writeTextureCoordinates(mesh)
|
||||
#--- output coordinates
|
||||
self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI)
|
||||
@ -540,9 +495,9 @@ class x3d_class:
|
||||
self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI)
|
||||
|
||||
#--- output textureCoordinates if UV texture used
|
||||
if mesh.active_uv_texture:
|
||||
if mesh.uv_textures.active:
|
||||
# if mesh.faceUV:
|
||||
if hasImageTexture == 1:
|
||||
if hasImageTexture == True:
|
||||
self.writeTextureCoordinates(mesh)
|
||||
elif self.matonly == 1 and self.share == 1:
|
||||
self.writeFaceColors(mesh)
|
||||
@ -614,7 +569,7 @@ class x3d_class:
|
||||
texIndexList=[]
|
||||
j=0
|
||||
|
||||
for face in mesh.active_uv_texture.data:
|
||||
for face in mesh.uv_textures.active.data:
|
||||
# for face in mesh.faces:
|
||||
# workaround, since tface.uv iteration is wrong atm
|
||||
uvs = face.uv
|
||||
@ -646,10 +601,10 @@ class x3d_class:
|
||||
def writeFaceColors(self, mesh):
|
||||
if self.writingcolor == 0:
|
||||
self.file.write("colorPerVertex=\"false\" ")
|
||||
elif mesh.active_vertex_color:
|
||||
elif mesh.vertex_colors.active:
|
||||
# else:
|
||||
self.writeIndented("<Color color=\"", 1)
|
||||
for face in mesh.active_vertex_color.data:
|
||||
for face in mesh.vertex_colors.active.data:
|
||||
c = face.color1
|
||||
if self.verbose > 2:
|
||||
print("Debug: face.col r=%d g=%d b=%d" % (c[0], c[1], c[2]))
|
||||
@ -717,21 +672,20 @@ class x3d_class:
|
||||
|
||||
def writeImageTexture(self, image):
|
||||
name = image.name
|
||||
filename = image.filepath.split('/')[-1].split('\\')[-1]
|
||||
filepath = os.path.basename(image.filepath)
|
||||
if name in self.texNames:
|
||||
self.writeIndented("<ImageTexture USE=\"%s\" />\n" % self.cleanStr(name))
|
||||
self.texNames[name] += 1
|
||||
return
|
||||
else:
|
||||
self.writeIndented("<ImageTexture DEF=\"%s\" " % self.cleanStr(name), 1)
|
||||
self.file.write("url=\"%s\" />" % name)
|
||||
self.file.write("url=\"%s\" />" % filepath)
|
||||
self.writeIndented("\n",-1)
|
||||
self.texNames[name] = 1
|
||||
|
||||
def writeBackground(self, world, alltextures):
|
||||
if world: worldname = world.name
|
||||
else: return
|
||||
blending = (world.blend_sky, world.paper_sky, world.use_sky_real)
|
||||
blending = (world.use_sky_blend, world.use_sky_paper, world.use_sky_real)
|
||||
# blending = world.getSkytype()
|
||||
grd = world.horizon_color
|
||||
# grd = world.getHor()
|
||||
@ -827,7 +781,7 @@ class x3d_class:
|
||||
EXPORT_TRI= False,\
|
||||
):
|
||||
|
||||
print("Info: starting X3D export to " + self.filename + "...")
|
||||
print("Info: starting X3D export to %r..." % self.filepath)
|
||||
self.writeHeader()
|
||||
# self.writeScript()
|
||||
self.writeNavigationInfo(scene)
|
||||
@ -925,7 +879,7 @@ class x3d_class:
|
||||
self.texNames={}
|
||||
self.matNames={}
|
||||
self.indentLevel=0
|
||||
print("Info: finished X3D export to %s\n" % self.filename)
|
||||
print("Info: finished X3D export to %r" % self.filepath)
|
||||
|
||||
def cleanStr(self, name, prefix='rsvd_'):
|
||||
"""cleanStr(name,prefix) - try to create a valid VRML DEF name from object name"""
|
||||
@ -961,9 +915,9 @@ class x3d_class:
|
||||
faceMap={}
|
||||
nFaceIndx=0
|
||||
|
||||
if mesh.active_uv_texture:
|
||||
if mesh.uv_textures.active:
|
||||
# if mesh.faceUV:
|
||||
for face in mesh.active_uv_texture.data:
|
||||
for face in mesh.uv_textures.active.data:
|
||||
# for face in mesh.faces
|
||||
sidename = "two" if face.use_twoside else "one"
|
||||
|
||||
@ -1135,91 +1089,35 @@ class x3d_class:
|
||||
# Callbacks, needed before Main
|
||||
##########################################################
|
||||
|
||||
def write(filename,
|
||||
context,
|
||||
EXPORT_APPLY_MODIFIERS=False,
|
||||
EXPORT_TRI=False,
|
||||
EXPORT_GZIP=False):
|
||||
def save(operator, context, filepath="",
|
||||
use_apply_modifiers=False,
|
||||
use_triangulate=False,
|
||||
use_compress=False):
|
||||
|
||||
if EXPORT_GZIP:
|
||||
if not filename.lower().endswith('.x3dz'):
|
||||
filename = '.'.join(filename.split('.')[:-1]) + '.x3dz'
|
||||
if use_compress:
|
||||
if not filepath.lower().endswith('.x3dz'):
|
||||
filepath = '.'.join(filepath.split('.')[:-1]) + '.x3dz'
|
||||
else:
|
||||
if not filename.lower().endswith('.x3d'):
|
||||
filename = '.'.join(filename.split('.')[:-1]) + '.x3d'
|
||||
|
||||
if not filepath.lower().endswith('.x3d'):
|
||||
filepath = '.'.join(filepath.split('.')[:-1]) + '.x3d'
|
||||
|
||||
scene = context.scene
|
||||
world = scene.world
|
||||
|
||||
if scene.objects.active:
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
# XXX these are global textures while .Get() returned only scene's?
|
||||
alltextures = bpy.data.textures
|
||||
# alltextures = Blender.Texture.Get()
|
||||
|
||||
wrlexport=x3d_class(filename)
|
||||
wrlexport.export(\
|
||||
scene,\
|
||||
world,\
|
||||
alltextures,\
|
||||
\
|
||||
EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS,\
|
||||
EXPORT_TRI = EXPORT_TRI,\
|
||||
)
|
||||
wrlexport = x3d_class(filepath)
|
||||
wrlexport.export(scene,
|
||||
world,
|
||||
alltextures,
|
||||
EXPORT_APPLY_MODIFIERS=use_apply_modifiers,
|
||||
EXPORT_TRI=use_triangulate,
|
||||
)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
from bpy.props import *
|
||||
|
||||
class ExportX3D(bpy.types.Operator):
|
||||
'''Export selection to Extensible 3D file (.x3d)'''
|
||||
bl_idname = "export.x3d"
|
||||
bl_label = 'Export X3D'
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the X3D file", maxlen= 1024, default= "")
|
||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
||||
|
||||
apply_modifiers = BoolProperty(name="Apply Modifiers", description="Use transformed mesh data from each object", default=True)
|
||||
triangulate = BoolProperty(name="Triangulate", description="Triangulate quads.", default=False)
|
||||
compress = BoolProperty(name="Compress", description="GZip the resulting file, requires a full python install", default=False)
|
||||
|
||||
def execute(self, context):
|
||||
filepath = self.properties.filepath
|
||||
filepath = bpy.path.ensure_ext(filepath, ".x3d")
|
||||
|
||||
write(filepath,
|
||||
context,
|
||||
self.properties.apply_modifiers,
|
||||
self.properties.triangulate,
|
||||
self.properties.compress,
|
||||
)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
import os
|
||||
if not self.properties.is_property_set("filepath"):
|
||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + ".x3d"
|
||||
|
||||
context.manager.add_fileselect(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(ExportX3D.bl_idname, text="X3D Extensible 3D (.x3d)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_export.append(menu_func)
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func)
|
||||
|
||||
# NOTES
|
||||
# - blender version is hardcoded
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
115
release/scripts/op/io_shape_mdd/__init__.py
Normal file
115
release/scripts/op/io_shape_mdd/__init__.py
Normal file
@ -0,0 +1,115 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# To support reload properly, try to access a package var, if it's there, reload everything
|
||||
if "bpy" in locals():
|
||||
# only reload if we alredy loaded, highly annoying
|
||||
import sys
|
||||
reload(sys.modules.get("io_shape_mdd.import_mdd", sys))
|
||||
reload(sys.modules.get("io_shape_mdd.export_mdd", sys))
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy.props import *
|
||||
from io_utils import ExportHelper, ImportHelper
|
||||
|
||||
|
||||
class ImportMDD(bpy.types.Operator, ImportHelper):
|
||||
'''Import MDD vertex keyframe file to shape keys'''
|
||||
bl_idname = "import_shape.mdd"
|
||||
bl_label = "Import MDD"
|
||||
|
||||
filename_ext = ".mdd"
|
||||
frame_start = IntProperty(name="Start Frame", description="Start frame for inserting animation", min=-300000, max=300000, default=0)
|
||||
frame_step = IntProperty(name="Step", min=1, max=1000, default=1)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.active_object
|
||||
return (ob and ob.type == 'MESH')
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
# initialize from scene if unset
|
||||
scene = context.scene
|
||||
if not self.properties.is_property_set("frame_start"):
|
||||
self.properties.frame_start = scene.frame_current
|
||||
|
||||
import io_shape_mdd.import_mdd
|
||||
return io_shape_mdd.import_mdd.load(self, context, **self.properties)
|
||||
|
||||
class ExportMDD(bpy.types.Operator, ExportHelper):
|
||||
'''Animated mesh to MDD vertex keyframe file'''
|
||||
bl_idname = "export_shape.mdd"
|
||||
bl_label = "Export MDD"
|
||||
|
||||
filename_ext = ".mdd"
|
||||
|
||||
# get first scene to get min and max properties for frames, fps
|
||||
|
||||
minframe = 1
|
||||
maxframe = 300000
|
||||
minfps = 1
|
||||
maxfps = 120
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
fps = IntProperty(name="Frames Per Second", description="Number of frames/second", min=minfps, max=maxfps, default=25)
|
||||
frame_start = IntProperty(name="Start Frame", description="Start frame for baking", min=minframe, max=maxframe, default=1)
|
||||
frame_end = IntProperty(name="End Frame", description="End frame for baking", min=minframe, max=maxframe, default=250)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
obj = context.active_object
|
||||
return (obj and obj.type == 'MESH')
|
||||
|
||||
def execute(self, context):
|
||||
# initialize from scene if unset
|
||||
scene = context.scene
|
||||
if not self.properties.is_property_set("frame_start"):
|
||||
self.properties.frame_start = scene.frame_start
|
||||
if not self.properties.is_property_set("frame_end"):
|
||||
self.properties.frame_end = scene.frame_end
|
||||
if not self.properties.is_property_set("fps"):
|
||||
self.properties.fps = scene.render.fps
|
||||
|
||||
import io_shape_mdd.export_mdd
|
||||
return io_shape_mdd.export_mdd.save(self, context, **self.properties)
|
||||
|
||||
|
||||
def menu_func_import(self, context):
|
||||
self.layout.operator(ImportMDD.bl_idname, text="Lightwave Point Cache (.mdd)")
|
||||
|
||||
|
||||
def menu_func_export(self, context):
|
||||
self.layout.operator(ExportMDD.bl_idname, text="Lightwave Point Cache (.mdd)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.INFO_MT_file_import.append(menu_func_import)
|
||||
bpy.types.INFO_MT_file_export.append(menu_func_export)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.INFO_MT_file_import.remove(menu_func_import)
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func_export)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
131
release/scripts/op/io_shape_mdd/export_mdd.py
Normal file
131
release/scripts/op/io_shape_mdd/export_mdd.py
Normal file
@ -0,0 +1,131 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# Contributors: Bill L.Nieuwendorp
|
||||
|
||||
"""
|
||||
This script Exports Lightwaves MotionDesigner format.
|
||||
|
||||
The .mdd format has become quite a popular Pipeline format<br>
|
||||
for moving animations from package to package.
|
||||
|
||||
Be sure not to use modifiers that change the number or order of verts in the mesh
|
||||
"""
|
||||
|
||||
import bpy
|
||||
import mathutils
|
||||
from struct import pack
|
||||
|
||||
|
||||
def zero_file(filepath):
|
||||
'''
|
||||
If a file fails, this replaces it with 1 char, better not remove it?
|
||||
'''
|
||||
file = open(filepath, 'w')
|
||||
file.write('\n') # apparently macosx needs some data in a blank file?
|
||||
file.close()
|
||||
|
||||
|
||||
def check_vertcount(mesh, vertcount):
|
||||
'''
|
||||
check and make sure the vertcount is consistent throughout the frame range
|
||||
'''
|
||||
if len(mesh.vertices) != vertcount:
|
||||
raise Exception('Error, number of verts has changed during animation, cannot export')
|
||||
f.close()
|
||||
zero_file(filepath)
|
||||
return
|
||||
|
||||
|
||||
def save(operator, context, filepath="", frame_start=1, frame_end=300, fps=25):
|
||||
"""
|
||||
Blender.Window.WaitCursor(1)
|
||||
|
||||
mesh_orig = Mesh.New()
|
||||
mesh_orig.getFromObject(obj.name)
|
||||
"""
|
||||
|
||||
scene = context.scene
|
||||
obj = context.object
|
||||
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
orig_frame = scene.frame_current
|
||||
scene.frame_set(frame_start)
|
||||
me = obj.create_mesh(scene, True, 'PREVIEW')
|
||||
|
||||
#Flip y and z
|
||||
mat_flip = mathutils.Matrix(\
|
||||
[1.0, 0.0, 0.0, 0.0],\
|
||||
[0.0, 0.0, 1.0, 0.0],\
|
||||
[0.0, 1.0, 0.0, 0.0],\
|
||||
[0.0, 0.0, 0.0, 1.0],\
|
||||
)
|
||||
|
||||
numverts = len(me.vertices)
|
||||
|
||||
numframes = frame_end - frame_start + 1
|
||||
fps = float(fps)
|
||||
f = open(filepath, 'wb') #no Errors yet:Safe to create file
|
||||
|
||||
# Write the header
|
||||
f.write(pack(">2i", numframes, numverts))
|
||||
|
||||
# Write the frame times (should we use the time IPO??)
|
||||
f.write(pack(">%df" % (numframes), *[frame / fps for frame in range(numframes)])) # seconds
|
||||
|
||||
#rest frame needed to keep frames in sync
|
||||
"""
|
||||
Blender.Set('curframe', frame_start)
|
||||
me_tmp.getFromObject(obj.name)
|
||||
"""
|
||||
|
||||
check_vertcount(me, numverts)
|
||||
me.transform(mat_flip * obj.matrix_world)
|
||||
f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
|
||||
|
||||
for frame in range(frame_start, frame_end + 1):#in order to start at desired frame
|
||||
"""
|
||||
Blender.Set('curframe', frame)
|
||||
me_tmp.getFromObject(obj.name)
|
||||
"""
|
||||
|
||||
scene.frame_set(frame)
|
||||
me = obj.create_mesh(scene, True, 'PREVIEW')
|
||||
check_vertcount(me, numverts)
|
||||
me.transform(mat_flip * obj.matrix_world)
|
||||
|
||||
# Write the vertex data
|
||||
f.write(pack(">%df" % (numverts * 3), *[axis for v in me.vertices for axis in v.co]))
|
||||
|
||||
"""
|
||||
me_tmp.vertices= None
|
||||
"""
|
||||
f.close()
|
||||
|
||||
print('MDD Exported: %r frames:%d\n' % (filepath, numframes - 1))
|
||||
"""
|
||||
Blender.Window.WaitCursor(0)
|
||||
Blender.Set('curframe', orig_frame)
|
||||
"""
|
||||
scene.frame_set(orig_frame)
|
||||
|
||||
return {'FINISHED'}
|
105
release/scripts/op/io_shape_mdd/import_mdd.py
Normal file
105
release/scripts/op/io_shape_mdd/import_mdd.py
Normal file
@ -0,0 +1,105 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# mdd importer by Bill L.Nieuwendorp
|
||||
# conversion to blender 2.5: Ivo Grigull (loolarge)
|
||||
#
|
||||
# Warning if the vertex order or vertex count differs from the
|
||||
# origonal model the mdd was Baked out from their will be Strange
|
||||
# behavior
|
||||
#
|
||||
# vertex animation to ShapeKeys with ipo and gives the frame a value of 1.0
|
||||
# A modifier to read mdd files would be Ideal but thats for another day :)
|
||||
#
|
||||
# Please send any fixes,updates,bugs to Slow67_at_Gmail.com
|
||||
# Bill Niewuendorp
|
||||
|
||||
import bpy
|
||||
from struct import unpack
|
||||
|
||||
|
||||
def load(operator, context, filepath, frame_start=0, frame_step=1):
|
||||
|
||||
scene = context.scene
|
||||
obj = context.object
|
||||
|
||||
print('\n\nimporting mdd %r' % filepath)
|
||||
|
||||
if bpy.ops.object.mode_set.poll():
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
file = open(filepath, 'rb')
|
||||
frames, points = unpack(">2i", file.read(8))
|
||||
time = unpack((">%df" % frames), file.read(frames * 4))
|
||||
|
||||
print('\tpoints:%d frames:%d' % (points, frames))
|
||||
|
||||
# If target object doesn't have Basis shape key, create it.
|
||||
try:
|
||||
num_keys = len(obj.data.shape_keys.keys)
|
||||
except:
|
||||
basis = obj.add_shape_key()
|
||||
basis.name = "Basis"
|
||||
obj.data.update()
|
||||
|
||||
scene.frame_current = frame_start
|
||||
|
||||
def UpdateMesh(ob, fr):
|
||||
|
||||
# Insert new shape key
|
||||
new_shapekey = obj.add_shape_key()
|
||||
new_shapekey.name = ("frame_%.4d" % fr)
|
||||
new_shapekey_name = new_shapekey.name
|
||||
|
||||
obj.active_shape_key_index = len(obj.data.shape_keys.keys)-1
|
||||
index = len(obj.data.shape_keys.keys)-1
|
||||
obj.show_shape_key = True
|
||||
|
||||
verts = obj.data.shape_keys.keys[len(obj.data.shape_keys.keys)-1].data
|
||||
|
||||
|
||||
for v in verts: # 12 is the size of 3 floats
|
||||
v.co[:] = unpack('>3f', file.read(12))
|
||||
#me.update()
|
||||
obj.show_shape_key = False
|
||||
|
||||
|
||||
# insert keyframes
|
||||
shape_keys = obj.data.shape_keys
|
||||
|
||||
scene.frame_current -= 1
|
||||
obj.data.shape_keys.keys[index].value = 0.0
|
||||
shape_keys.keys[len(obj.data.shape_keys.keys)-1].keyframe_insert("value")
|
||||
|
||||
scene.frame_current += 1
|
||||
obj.data.shape_keys.keys[index].value = 1.0
|
||||
shape_keys.keys[len(obj.data.shape_keys.keys)-1].keyframe_insert("value")
|
||||
|
||||
scene.frame_current += 1
|
||||
obj.data.shape_keys.keys[index].value = 0.0
|
||||
shape_keys.keys[len(obj.data.shape_keys.keys)-1].keyframe_insert("value")
|
||||
|
||||
obj.data.update()
|
||||
|
||||
|
||||
for i in range(frames):
|
||||
UpdateMesh(obj, i)
|
||||
|
||||
return {'FINISHED'}
|
@ -87,7 +87,7 @@ def bake(frame_start, frame_end, step=1, only_selected=False):
|
||||
|
||||
# could spped this up by applying steps here too...
|
||||
for f in frame_range:
|
||||
scene.set_frame(f)
|
||||
scene.frame_set(f)
|
||||
|
||||
info = pose_info()
|
||||
info_ls.append(info)
|
||||
@ -169,7 +169,7 @@ class BakeAction(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm = context.window_manager
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
||||
|
||||
|
@ -59,7 +59,7 @@ class SelectPattern(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm = context.window_manager
|
||||
# return wm.invoke_props_popup(self, event)
|
||||
wm.invoke_props_popup(self, event)
|
||||
return {'RUNNING_MODAL'}
|
||||
@ -427,13 +427,13 @@ class JoinUVs(bpy.types.Operator):
|
||||
if is_editmode:
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
if not mesh.active_uv_texture:
|
||||
if not mesh.uv_textures:
|
||||
self.report({'WARNING'}, "Object: %s, Mesh: '%s' has no UVs\n" % (obj.name, mesh.name))
|
||||
else:
|
||||
len_faces = len(mesh.faces)
|
||||
|
||||
uv_array = array.array('f', [0.0] * 8) * len_faces # seems to be the fastest way to create an array
|
||||
mesh.active_uv_texture.data.foreach_get("uv_raw", uv_array)
|
||||
mesh.uv_textures.active.data.foreach_get("uv_raw", uv_array)
|
||||
|
||||
objects = context.selected_editable_objects[:]
|
||||
|
||||
@ -451,10 +451,9 @@ class JoinUVs(bpy.types.Operator):
|
||||
if len(mesh_other.faces) != len_faces:
|
||||
self.report({'WARNING'}, "Object: %s, Mesh: '%s' has %d faces, expected %d\n" % (obj_other.name, mesh_other.name, len(mesh_other.faces), len_faces))
|
||||
else:
|
||||
uv_other = mesh_other.active_uv_texture
|
||||
uv_other = mesh_other.uv_textures.active
|
||||
if not uv_other:
|
||||
mesh_other.add_uv_texture() # should return the texture it adds
|
||||
uv_other = mesh_other.active_uv_texture
|
||||
uv_other = mesh_other.uv_textures.new() # should return the texture it adds
|
||||
|
||||
# finally do the copy
|
||||
uv_other.data.foreach_set("uv_raw", uv_array)
|
||||
@ -500,11 +499,13 @@ class MakeDupliFace(bpy.types.Operator):
|
||||
|
||||
for data, objects in linked.items():
|
||||
face_verts = [axis for obj in objects for v in matrix_to_quat(obj.matrix_world) for axis in v]
|
||||
faces = list(range(int(len(face_verts) / 3)))
|
||||
faces = list(range(len(face_verts) // 3))
|
||||
|
||||
mesh = bpy.data.meshes.new(data.name + "_dupli")
|
||||
|
||||
mesh.add_geometry(int(len(face_verts) / 3), 0, int(len(face_verts) / (4 * 3)))
|
||||
mesh.vertices.add(len(face_verts) // 3)
|
||||
mesh.faces.add(len(face_verts) // 12)
|
||||
|
||||
mesh.vertices.foreach_set("co", face_verts)
|
||||
mesh.faces.foreach_set("vertices_raw", faces)
|
||||
mesh.update() # generates edge data
|
||||
@ -572,4 +573,4 @@ def unregister():
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
register()
|
||||
|
@ -50,7 +50,7 @@ class AddPresetBase():
|
||||
if getattr(self, "save_keyconfig", False):
|
||||
bpy.ops.wm.keyconfig_export(filepath=filepath, kc_name=self.properties.name)
|
||||
file_preset = open(filepath, 'a')
|
||||
file_preset.write("wm.active_keyconfig = kc\n\n")
|
||||
file_preset.write("wm.keyconfigs.active = kc\n\n")
|
||||
else:
|
||||
file_preset = open(filepath, 'w')
|
||||
file_preset.write("import bpy\n")
|
||||
@ -64,7 +64,7 @@ class AddPresetBase():
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm = context.window_manager
|
||||
#crashes, TODO - fix
|
||||
#return wm.invoke_props_popup(self, event)
|
||||
|
||||
|
@ -69,7 +69,7 @@ class ExportUVLayout(bpy.types.Operator):
|
||||
def _face_uv_iter(self, context):
|
||||
obj = context.active_object
|
||||
mesh = obj.data
|
||||
uv_layer = mesh.active_uv_texture.data
|
||||
uv_layer = mesh.uv_textures.active.data
|
||||
uv_layer_len = len(uv_layer)
|
||||
|
||||
if not self.properties.export_all:
|
||||
@ -207,7 +207,7 @@ class ExportUVLayout(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm = context.window_manager
|
||||
wm.add_fileselect(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
@ -28,8 +28,8 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
me = obj.data
|
||||
me_verts = me.vertices
|
||||
# script will fail without UVs
|
||||
if not me.active_uv_texture:
|
||||
me.add_uv_texture()
|
||||
if not me.uv_textures:
|
||||
me.uv_textures.new()
|
||||
|
||||
|
||||
# Toggle Edit mode
|
||||
@ -57,10 +57,10 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
vidx_source = face_source.vertices
|
||||
vidx_target = face_target.vertices
|
||||
|
||||
faceUVsource = me.active_uv_texture.data[face_source.index]
|
||||
faceUVsource = me.uv_textures.active.data[face_source.index]
|
||||
uvs_source = [faceUVsource.uv1, faceUVsource.uv2, faceUVsource.uv3, faceUVsource.uv4]
|
||||
|
||||
faceUVtarget = me.active_uv_texture.data[face_target.index]
|
||||
faceUVtarget = me.uv_textures.active.data[face_target.index]
|
||||
uvs_target = [faceUVtarget.uv1, faceUVtarget.uv2, faceUVtarget.uv3, faceUVtarget.uv4]
|
||||
|
||||
# vertex index is the key, uv is the value
|
||||
@ -138,8 +138,8 @@ def extend(obj, operator, EXTEND_MODE):
|
||||
uvs_vhash_target[edgepair_outer_target[iA]][:] = uvs_vhash_source[edgepair_inner_source[1]] + (uvs_vhash_source[edgepair_inner_source[1]] - uvs_vhash_source[edgepair_outer_source[0]])
|
||||
|
||||
|
||||
if me.active_uv_texture == None:
|
||||
me.add_uv_texture
|
||||
if not me.uv_textures:
|
||||
me.uv_textures.new()
|
||||
|
||||
face_act = me.faces.active
|
||||
if face_act == -1:
|
||||
|
@ -892,10 +892,10 @@ def main(context, island_margin, projection_limit):
|
||||
# Tag as used
|
||||
me.tag = True
|
||||
|
||||
if len(me.uv_textures)==0: # Mesh has no UV Coords, dont bother.
|
||||
me.add_uv_texture()
|
||||
if not me.uv_textures: # Mesh has no UV Coords, dont bother.
|
||||
me.uv_textures.new()
|
||||
|
||||
uv_layer = me.active_uv_texture.data
|
||||
uv_layer = me.uv_textures.active.data
|
||||
me_verts = list(me.vertices)
|
||||
|
||||
if USER_ONLY_SELECTED_FACES:
|
||||
|
@ -449,7 +449,7 @@ class WM_OT_context_modal_mouse(bpy.types.Operator):
|
||||
else:
|
||||
self.properties.initial_x = event.mouse_x
|
||||
|
||||
context.manager.add_modal_handler(self)
|
||||
context.window_manager.add_modal_handler(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
||||
@ -505,7 +505,7 @@ class WM_OT_doc_view(bpy.types.Operator):
|
||||
bl_label = "View Documentation"
|
||||
|
||||
doc_id = doc_id
|
||||
_prefix = 'http://www.blender.org/documentation/250PythonDoc'
|
||||
_prefix = "http://www.blender.org/documentation/blender_python_api_%s" % "_".join(str(v) for v in bpy.app.version)
|
||||
|
||||
def _nested_class_string(self, class_string):
|
||||
ls = []
|
||||
@ -608,7 +608,7 @@ class WM_OT_doc_edit(bpy.types.Operator):
|
||||
layout.prop(props, "doc_new", text="")
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm = context.window_manager
|
||||
return wm.invoke_props_dialog(self, width=600)
|
||||
|
||||
|
||||
@ -692,7 +692,7 @@ class WM_OT_properties_edit(bpy.types.Operator):
|
||||
self.properties.max = prop_ui.get("max", 1000000000)
|
||||
self.properties.description = prop_ui.get("description", "")
|
||||
|
||||
wm = context.manager
|
||||
wm = context.window_manager
|
||||
# This crashes, TODO - fix
|
||||
#return wm.invoke_props_popup(self, event)
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
# Configuration Blender
|
||||
import bpy
|
||||
|
||||
wm = bpy.context.manager
|
||||
wm.active_keyconfig = wm.keyconfigs['Blender']
|
||||
wm = bpy.context.window_manager
|
||||
wm.keyconfigs.active = wm.keyconfigs['Blender']
|
||||
|
||||
bpy.context.user_preferences.view.use_mouse_auto_depth = False
|
||||
bpy.context.user_preferences.view.use_zoom_to_mouse = False
|
||||
|
@ -1,381 +1,381 @@
|
||||
# Configuration Maya
|
||||
import bpy
|
||||
|
||||
wm = bpy.context.manager
|
||||
kc = wm.add_keyconfig('Maya')
|
||||
wm = bpy.context.window_manager
|
||||
kc = wm.keyconfigs.new('Maya')
|
||||
|
||||
# Map 3D View
|
||||
km = kc.add_keymap('3D View', space_type='VIEW_3D', region_type='WINDOW', modal=False)
|
||||
km = kc.keymaps.new('3D View', space_type='VIEW_3D', region_type='WINDOW', modal=False)
|
||||
|
||||
kmi = km.items.add('view3d.show_manipulator', 'LEFTMOUSE', 'PRESS', any=True)
|
||||
kmi = km.items.new('view3d.manipulator', 'LEFTMOUSE', 'PRESS', any=True)
|
||||
kmi.properties.release_confirm = True
|
||||
kmi = km.items.add('view3d.cursor3d', 'ACTIONMOUSE', 'PRESS')
|
||||
kmi = km.items.add('view3d.rotate', 'LEFTMOUSE', 'PRESS', alt=True)
|
||||
kmi = km.items.add('view3d.move', 'MIDDLEMOUSE', 'PRESS', alt=True)
|
||||
kmi = km.items.add('view3d.zoom', 'RIGHTMOUSE', 'PRESS', alt=True)
|
||||
kmi = km.items.add('view3d.view_selected', 'NUMPAD_PERIOD', 'PRESS')
|
||||
kmi = km.items.add('view3d.view_center_cursor', 'NUMPAD_PERIOD', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('view3d.fly', 'F', 'PRESS', shift=True)
|
||||
kmi = km.items.add('view3d.smoothview', 'TIMER1', 'ANY', any=True)
|
||||
kmi = km.items.add('view3d.rotate', 'TRACKPADPAN', 'ANY', alt=True)
|
||||
kmi = km.items.add('view3d.rotate', 'MOUSEROTATE', 'ANY')
|
||||
kmi = km.items.add('view3d.move', 'TRACKPADPAN', 'ANY')
|
||||
kmi = km.items.add('view3d.zoom', 'TRACKPADZOOM', 'ANY')
|
||||
kmi = km.items.add('view3d.zoom', 'NUMPAD_PLUS', 'PRESS')
|
||||
kmi = km.items.new('view3d.cursor3d', 'ACTIONMOUSE', 'PRESS')
|
||||
kmi = km.items.new('view3d.rotate', 'LEFTMOUSE', 'PRESS', alt=True)
|
||||
kmi = km.items.new('view3d.move', 'MIDDLEMOUSE', 'PRESS', alt=True)
|
||||
kmi = km.items.new('view3d.zoom', 'RIGHTMOUSE', 'PRESS', alt=True)
|
||||
kmi = km.items.new('view3d.view_selected', 'NUMPAD_PERIOD', 'PRESS')
|
||||
kmi = km.items.new('view3d.view_center_cursor', 'NUMPAD_PERIOD', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.fly', 'F', 'PRESS', shift=True)
|
||||
kmi = km.items.new('view3d.smoothview', 'TIMER1', 'ANY', any=True)
|
||||
kmi = km.items.new('view3d.rotate', 'TRACKPADPAN', 'ANY', alt=True)
|
||||
kmi = km.items.new('view3d.rotate', 'MOUSEROTATE', 'ANY')
|
||||
kmi = km.items.new('view3d.move', 'TRACKPADPAN', 'ANY')
|
||||
kmi = km.items.new('view3d.zoom', 'TRACKPADZOOM', 'ANY')
|
||||
kmi = km.items.new('view3d.zoom', 'NUMPAD_PLUS', 'PRESS')
|
||||
kmi.properties.delta = 1
|
||||
kmi = km.items.add('view3d.zoom', 'NUMPAD_MINUS', 'PRESS')
|
||||
kmi = km.items.new('view3d.zoom', 'NUMPAD_MINUS', 'PRESS')
|
||||
kmi.properties.delta = -1
|
||||
kmi = km.items.add('view3d.zoom', 'EQUAL', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.zoom', 'EQUAL', 'PRESS', ctrl=True)
|
||||
kmi.properties.delta = 1
|
||||
kmi = km.items.add('view3d.zoom', 'MINUS', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.zoom', 'MINUS', 'PRESS', ctrl=True)
|
||||
kmi.properties.delta = -1
|
||||
kmi = km.items.add('view3d.zoom', 'WHEELINMOUSE', 'PRESS')
|
||||
kmi = km.items.new('view3d.zoom', 'WHEELINMOUSE', 'PRESS')
|
||||
kmi.properties.delta = 1
|
||||
kmi = km.items.add('view3d.zoom', 'WHEELOUTMOUSE', 'PRESS')
|
||||
kmi = km.items.new('view3d.zoom', 'WHEELOUTMOUSE', 'PRESS')
|
||||
kmi.properties.delta = -1
|
||||
kmi = km.items.add('view3d.view_all', 'HOME', 'PRESS')
|
||||
kmi = km.items.new('view3d.view_all', 'HOME', 'PRESS')
|
||||
kmi.properties.center = False
|
||||
kmi = km.items.add('view3d.view_all', 'C', 'PRESS', shift=True)
|
||||
kmi = km.items.new('view3d.view_all', 'C', 'PRESS', shift=True)
|
||||
kmi.properties.center = True
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_0', 'PRESS')
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_0', 'PRESS')
|
||||
kmi.properties.type = 'CAMERA'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_1', 'PRESS')
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS')
|
||||
kmi.properties.type = 'FRONT'
|
||||
kmi = km.items.add('view3d.view_orbit', 'NUMPAD_2', 'PRESS')
|
||||
kmi = km.items.new('view3d.view_orbit', 'NUMPAD_2', 'PRESS')
|
||||
kmi.properties.type = 'ORBITDOWN'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_3', 'PRESS')
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS')
|
||||
kmi.properties.type = 'RIGHT'
|
||||
kmi = km.items.add('view3d.view_orbit', 'NUMPAD_4', 'PRESS')
|
||||
kmi = km.items.new('view3d.view_orbit', 'NUMPAD_4', 'PRESS')
|
||||
kmi.properties.type = 'ORBITLEFT'
|
||||
kmi = km.items.add('view3d.view_persportho', 'NUMPAD_5', 'PRESS')
|
||||
kmi = km.items.add('view3d.view_orbit', 'NUMPAD_6', 'PRESS')
|
||||
kmi = km.items.new('view3d.view_persportho', 'NUMPAD_5', 'PRESS')
|
||||
kmi = km.items.new('view3d.view_orbit', 'NUMPAD_6', 'PRESS')
|
||||
kmi.properties.type = 'ORBITRIGHT'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_7', 'PRESS')
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS')
|
||||
kmi.properties.type = 'TOP'
|
||||
kmi = km.items.add('view3d.view_orbit', 'NUMPAD_8', 'PRESS')
|
||||
kmi = km.items.new('view3d.view_orbit', 'NUMPAD_8', 'PRESS')
|
||||
kmi.properties.type = 'ORBITUP'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', ctrl=True)
|
||||
kmi.properties.type = 'BACK'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', ctrl=True)
|
||||
kmi.properties.type = 'LEFT'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', ctrl=True)
|
||||
kmi.properties.type = 'BOTTOM'
|
||||
kmi = km.items.add('view3d.view_pan', 'NUMPAD_2', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.view_pan', 'NUMPAD_2', 'PRESS', ctrl=True)
|
||||
kmi.properties.type = 'PANDOWN'
|
||||
kmi = km.items.add('view3d.view_pan', 'NUMPAD_4', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.view_pan', 'NUMPAD_4', 'PRESS', ctrl=True)
|
||||
kmi.properties.type = 'PANLEFT'
|
||||
kmi = km.items.add('view3d.view_pan', 'NUMPAD_6', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.view_pan', 'NUMPAD_6', 'PRESS', ctrl=True)
|
||||
kmi.properties.type = 'PANRIGHT'
|
||||
kmi = km.items.add('view3d.view_pan', 'NUMPAD_8', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.view_pan', 'NUMPAD_8', 'PRESS', ctrl=True)
|
||||
kmi.properties.type = 'PANUP'
|
||||
kmi = km.items.add('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', ctrl=True)
|
||||
kmi.properties.type = 'PANRIGHT'
|
||||
kmi = km.items.add('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True)
|
||||
kmi.properties.type = 'PANLEFT'
|
||||
kmi = km.items.add('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', shift=True)
|
||||
kmi = km.items.new('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', shift=True)
|
||||
kmi.properties.type = 'PANUP'
|
||||
kmi = km.items.add('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', shift=True)
|
||||
kmi = km.items.new('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', shift=True)
|
||||
kmi.properties.type = 'PANDOWN'
|
||||
kmi = km.items.add('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.new('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi.properties.type = 'ORBITLEFT'
|
||||
kmi = km.items.add('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.new('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi.properties.type = 'ORBITRIGHT'
|
||||
kmi = km.items.add('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', shift=True, alt=True)
|
||||
kmi = km.items.new('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', shift=True, alt=True)
|
||||
kmi.properties.type = 'ORBITUP'
|
||||
kmi = km.items.add('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', shift=True, alt=True)
|
||||
kmi = km.items.new('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', shift=True, alt=True)
|
||||
kmi.properties.type = 'ORBITDOWN'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True)
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True)
|
||||
kmi.properties.align_active = True
|
||||
kmi.properties.type = 'FRONT'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True)
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True)
|
||||
kmi.properties.align_active = True
|
||||
kmi.properties.type = 'RIGHT'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True)
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True)
|
||||
kmi.properties.align_active = True
|
||||
kmi.properties.type = 'TOP'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True, ctrl=True)
|
||||
kmi.properties.align_active = True
|
||||
kmi.properties.type = 'BACK'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True, ctrl=True)
|
||||
kmi.properties.align_active = True
|
||||
kmi.properties.type = 'LEFT'
|
||||
kmi = km.items.add('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True, ctrl=True)
|
||||
kmi.properties.align_active = True
|
||||
kmi.properties.type = 'BOTTOM'
|
||||
kmi = km.items.add('view3d.localview', 'NUMPAD_SLASH', 'PRESS')
|
||||
kmi = km.items.add('view3d.layers', 'ACCENT_GRAVE', 'PRESS')
|
||||
kmi = km.items.new('view3d.localview', 'NUMPAD_SLASH', 'PRESS')
|
||||
kmi = km.items.new('view3d.layers', 'ACCENT_GRAVE', 'PRESS')
|
||||
kmi.properties.nr = 0
|
||||
kmi = km.items.add('view3d.layers', 'ONE', 'PRESS', any=True)
|
||||
kmi = km.items.new('view3d.layers', 'ONE', 'PRESS', any=True)
|
||||
kmi.properties.nr = 1
|
||||
kmi = km.items.add('view3d.layers', 'TWO', 'PRESS', any=True)
|
||||
kmi = km.items.new('view3d.layers', 'TWO', 'PRESS', any=True)
|
||||
kmi.properties.nr = 2
|
||||
kmi = km.items.add('view3d.layers', 'THREE', 'PRESS', any=True)
|
||||
kmi = km.items.new('view3d.layers', 'THREE', 'PRESS', any=True)
|
||||
kmi.properties.nr = 3
|
||||
kmi = km.items.add('view3d.layers', 'FOUR', 'PRESS', any=True)
|
||||
kmi = km.items.new('view3d.layers', 'FOUR', 'PRESS', any=True)
|
||||
kmi.properties.nr = 4
|
||||
kmi = km.items.add('view3d.layers', 'FIVE', 'PRESS', any=True)
|
||||
kmi = km.items.new('view3d.layers', 'FIVE', 'PRESS', any=True)
|
||||
kmi.properties.nr = 5
|
||||
kmi = km.items.add('view3d.layers', 'SIX', 'PRESS', any=True)
|
||||
kmi = km.items.new('view3d.layers', 'SIX', 'PRESS', any=True)
|
||||
kmi.properties.nr = 6
|
||||
kmi = km.items.add('view3d.layers', 'SEVEN', 'PRESS', any=True)
|
||||
kmi = km.items.new('view3d.layers', 'SEVEN', 'PRESS', any=True)
|
||||
kmi.properties.nr = 7
|
||||
kmi = km.items.add('view3d.layers', 'EIGHT', 'PRESS', any=True)
|
||||
kmi = km.items.new('view3d.layers', 'EIGHT', 'PRESS', any=True)
|
||||
kmi.properties.nr = 8
|
||||
kmi = km.items.add('view3d.layers', 'NINE', 'PRESS', any=True)
|
||||
kmi = km.items.new('view3d.layers', 'NINE', 'PRESS', any=True)
|
||||
kmi.properties.nr = 9
|
||||
kmi = km.items.add('view3d.layers', 'ZERO', 'PRESS', any=True)
|
||||
kmi = km.items.new('view3d.layers', 'ZERO', 'PRESS', any=True)
|
||||
kmi.properties.nr = 10
|
||||
kmi = km.items.add('wm.context_toggle_enum', 'Z', 'PRESS')
|
||||
kmi = km.items.new('wm.context_toggle_enum', 'Z', 'PRESS')
|
||||
kmi.properties.data_path = 'space_data.viewport_shade'
|
||||
kmi.properties.value_1 = 'SOLID'
|
||||
kmi.properties.value_2 = 'WIREFRAME'
|
||||
kmi = km.items.add('wm.context_toggle_enum', 'Z', 'PRESS', alt=True)
|
||||
kmi = km.items.new('wm.context_toggle_enum', 'Z', 'PRESS', alt=True)
|
||||
kmi.properties.data_path = 'space_data.viewport_shade'
|
||||
kmi.properties.value_1 = 'TEXTURED'
|
||||
kmi.properties.value_2 = 'SOLID'
|
||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS')
|
||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True)
|
||||
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS')
|
||||
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True)
|
||||
kmi.properties.extend = True
|
||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True)
|
||||
kmi.properties.center = True
|
||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', alt=True)
|
||||
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', alt=True)
|
||||
kmi.properties.enumerate = True
|
||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True)
|
||||
kmi.properties.center = True
|
||||
kmi.properties.extend = True
|
||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi.properties.center = True
|
||||
kmi.properties.enumerate = True
|
||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
|
||||
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
|
||||
kmi.properties.enumerate = True
|
||||
kmi.properties.extend = True
|
||||
kmi = km.items.add('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi = km.items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi.properties.center = True
|
||||
kmi.properties.enumerate = True
|
||||
kmi.properties.extend = True
|
||||
kmi = km.items.add('view3d.select_border', 'EVT_TWEAK_S', 'ANY')
|
||||
kmi = km.items.new('view3d.select_border', 'EVT_TWEAK_S', 'ANY')
|
||||
kmi.properties.extend = False
|
||||
kmi = km.items.add('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', ctrl=True)
|
||||
kmi = km.items.add('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', shift=True, ctrl=True)
|
||||
kmi = km.items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', ctrl=True)
|
||||
kmi = km.items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', shift=True, ctrl=True)
|
||||
kmi.properties.deselect = True
|
||||
kmi = km.items.add('view3d.select_circle', 'C', 'PRESS')
|
||||
kmi = km.items.add('view3d.clip_border', 'B', 'PRESS', alt=True)
|
||||
kmi = km.items.add('view3d.zoom_border', 'B', 'PRESS', shift=True)
|
||||
kmi = km.items.add('view3d.render_border', 'B', 'PRESS', shift=True)
|
||||
kmi = km.items.add('view3d.camera_to_view', 'NUMPAD_0', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.add('view3d.object_as_camera', 'NUMPAD_0', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('wm.call_menu', 'S', 'PRESS', shift=True)
|
||||
kmi = km.items.new('view3d.select_circle', 'C', 'PRESS')
|
||||
kmi = km.items.new('view3d.clip_border', 'B', 'PRESS', alt=True)
|
||||
kmi = km.items.new('view3d.zoom_border', 'B', 'PRESS', shift=True)
|
||||
kmi = km.items.new('view3d.render_border', 'B', 'PRESS', shift=True)
|
||||
kmi = km.items.new('view3d.camera_to_view', 'NUMPAD_0', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.new('view3d.object_as_camera', 'NUMPAD_0', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('wm.call_menu', 'S', 'PRESS', shift=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_snap'
|
||||
kmi = km.items.add('wm.context_set_enum', 'COMMA', 'PRESS')
|
||||
kmi = km.items.new('wm.context_set_enum', 'COMMA', 'PRESS')
|
||||
kmi.properties.data_path = 'space_data.pivot_point'
|
||||
kmi.properties.value = 'BOUNDING_BOX_CENTER'
|
||||
kmi = km.items.add('wm.context_set_enum', 'COMMA', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('wm.context_set_enum', 'COMMA', 'PRESS', ctrl=True)
|
||||
kmi.properties.data_path = 'space_data.pivot_point'
|
||||
kmi.properties.value = 'MEDIAN_POINT'
|
||||
kmi = km.items.add('wm.context_toggle', 'COMMA', 'PRESS', alt=True)
|
||||
kmi = km.items.new('wm.context_toggle', 'COMMA', 'PRESS', alt=True)
|
||||
kmi.properties.data_path = 'space_data.use_pivot_point_align'
|
||||
kmi = km.items.add('wm.context_toggle', 'Q', 'PRESS')
|
||||
kmi = km.items.new('wm.context_toggle', 'Q', 'PRESS')
|
||||
kmi.properties.data_path = 'space_data.show_manipulator'
|
||||
kmi = km.items.add('wm.context_set_enum', 'PERIOD', 'PRESS')
|
||||
kmi = km.items.new('wm.context_set_enum', 'PERIOD', 'PRESS')
|
||||
kmi.properties.data_path = 'space_data.pivot_point'
|
||||
kmi.properties.value = 'CURSOR'
|
||||
kmi = km.items.add('wm.context_set_enum', 'PERIOD', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('wm.context_set_enum', 'PERIOD', 'PRESS', ctrl=True)
|
||||
kmi.properties.data_path = 'space_data.pivot_point'
|
||||
kmi.properties.value = 'INDIVIDUAL_ORIGINS'
|
||||
kmi = km.items.add('wm.context_set_enum', 'PERIOD', 'PRESS', alt=True)
|
||||
kmi = km.items.new('wm.context_set_enum', 'PERIOD', 'PRESS', alt=True)
|
||||
kmi.properties.data_path = 'space_data.pivot_point'
|
||||
kmi.properties.value = 'ACTIVE_ELEMENT'
|
||||
kmi = km.items.add('transform.translate', 'G', 'PRESS', shift=True)
|
||||
kmi = km.items.add('transform.translate', 'EVT_TWEAK_S', 'ANY')
|
||||
kmi = km.items.add('transform.rotate', 'R', 'PRESS', shift=True)
|
||||
kmi = km.items.add('transform.resize', 'S', 'PRESS', shift=True)
|
||||
kmi = km.items.add('transform.warp', 'W', 'PRESS', shift=True)
|
||||
kmi = km.items.add('transform.tosphere', 'S', 'PRESS', shift=True, alt=True)
|
||||
kmi = km.items.add('transform.shear', 'S', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi = km.items.add('transform.select_orientation', 'SPACE', 'PRESS', alt=True)
|
||||
kmi = km.items.add('transform.create_orientation', 'SPACE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.new('transform.translate', 'G', 'PRESS', shift=True)
|
||||
kmi = km.items.new('transform.translate', 'EVT_TWEAK_S', 'ANY')
|
||||
kmi = km.items.new('transform.rotate', 'R', 'PRESS', shift=True)
|
||||
kmi = km.items.new('transform.resize', 'S', 'PRESS', shift=True)
|
||||
kmi = km.items.new('transform.warp', 'W', 'PRESS', shift=True)
|
||||
kmi = km.items.new('transform.tosphere', 'S', 'PRESS', shift=True, alt=True)
|
||||
kmi = km.items.new('transform.shear', 'S', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi = km.items.new('transform.select_orientation', 'SPACE', 'PRESS', alt=True)
|
||||
kmi = km.items.new('transform.create_orientation', 'SPACE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi.properties.use = True
|
||||
kmi = km.items.add('transform.mirror', 'M', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('wm.context_toggle', 'TAB', 'PRESS', shift=True)
|
||||
kmi.properties.data_path = 'tool_settings.snap'
|
||||
kmi = km.items.add('transform.snap_type', 'TAB', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.add('view3d.enable_manipulator', 'W', 'PRESS')
|
||||
kmi = km.items.new('transform.mirror', 'M', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('wm.context_toggle', 'TAB', 'PRESS', shift=True)
|
||||
kmi.properties.data_path = 'tool_settings.use_snap'
|
||||
kmi = km.items.new('transform.snap_type', 'TAB', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('view3d.enable_manipulator', 'W', 'PRESS')
|
||||
kmi.properties.translate = True
|
||||
kmi = km.items.add('view3d.enable_manipulator', 'E', 'PRESS')
|
||||
kmi = km.items.new('view3d.enable_manipulator', 'E', 'PRESS')
|
||||
kmi.properties.rotate = True
|
||||
kmi = km.items.add('view3d.enable_manipulator', 'R', 'PRESS')
|
||||
kmi = km.items.new('view3d.enable_manipulator', 'R', 'PRESS')
|
||||
kmi.properties.scale = True
|
||||
kmi = km.items.add('view3d.select_border', 'EVT_TWEAK_S', 'ANY', shift=True)
|
||||
kmi = km.items.new('view3d.select_border', 'EVT_TWEAK_S', 'ANY', shift=True)
|
||||
kmi.properties.extend = True
|
||||
|
||||
# Map Object Mode
|
||||
km = kc.add_keymap('Object Mode', space_type='EMPTY', region_type='WINDOW', modal=False)
|
||||
km = kc.keymaps.new('Object Mode', space_type='EMPTY', region_type='WINDOW', modal=False)
|
||||
|
||||
kmi = km.items.add('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
|
||||
kmi = km.items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
|
||||
kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
|
||||
kmi = km.items.add('wm.context_toggle_enum', 'O', 'PRESS')
|
||||
kmi = km.items.new('wm.context_toggle_enum', 'O', 'PRESS')
|
||||
kmi.properties.data_path = 'tool_settings.proportional_edit'
|
||||
kmi.properties.value_1 = 'DISABLED'
|
||||
kmi.properties.value_2 = 'ENABLED'
|
||||
kmi = km.items.add('view3d.game_start', 'P', 'PRESS')
|
||||
kmi = km.items.add('object.select_all', 'A', 'PRESS')
|
||||
kmi = km.items.add('object.select_inverse', 'I', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('object.select_linked', 'L', 'PRESS', shift=True)
|
||||
kmi = km.items.add('object.select_grouped', 'G', 'PRESS', shift=True)
|
||||
kmi = km.items.add('object.select_mirror', 'M', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.add('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS')
|
||||
kmi = km.items.new('view3d.game_start', 'P', 'PRESS')
|
||||
kmi = km.items.new('object.select_all', 'A', 'PRESS')
|
||||
kmi = km.items.new('object.select_inverse', 'I', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.select_linked', 'L', 'PRESS', shift=True)
|
||||
kmi = km.items.new('object.select_grouped', 'G', 'PRESS', shift=True)
|
||||
kmi = km.items.new('object.select_mirror', 'M', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS')
|
||||
kmi.properties.direction = 'PARENT'
|
||||
kmi = km.items.add('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS', shift=True)
|
||||
kmi = km.items.new('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS', shift=True)
|
||||
kmi.properties.direction = 'PARENT'
|
||||
kmi.properties.extend = True
|
||||
kmi = km.items.add('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS')
|
||||
kmi = km.items.new('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS')
|
||||
kmi.properties.direction = 'CHILD'
|
||||
kmi = km.items.add('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS', shift=True)
|
||||
kmi = km.items.new('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS', shift=True)
|
||||
kmi.properties.direction = 'CHILD'
|
||||
kmi.properties.extend = True
|
||||
kmi = km.items.add('object.parent_set', 'P', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('object.parent_no_inverse_set', 'P', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.add('object.parent_clear', 'P', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.track_set', 'T', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('object.track_clear', 'T', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.constraint_add_with_targets', 'C', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.add('object.constraints_clear', 'C', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.add('object.location_clear', 'G', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.rotation_clear', 'R', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.scale_clear', 'S', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.origin_clear', 'O', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.hide_view_clear', 'H', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.hide_view_set', 'H', 'PRESS')
|
||||
kmi = km.items.add('object.hide_view_set', 'H', 'PRESS', shift=True)
|
||||
kmi = km.items.new('object.parent_set', 'P', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.parent_no_inverse_set', 'P', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('object.parent_clear', 'P', 'PRESS', alt=True)
|
||||
kmi = km.items.new('object.track_set', 'T', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.track_clear', 'T', 'PRESS', alt=True)
|
||||
kmi = km.items.new('object.constraint_add_with_targets', 'C', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('object.constraints_clear', 'C', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.new('object.location_clear', 'G', 'PRESS', alt=True)
|
||||
kmi = km.items.new('object.rotation_clear', 'R', 'PRESS', alt=True)
|
||||
kmi = km.items.new('object.scale_clear', 'S', 'PRESS', alt=True)
|
||||
kmi = km.items.new('object.origin_clear', 'O', 'PRESS', alt=True)
|
||||
kmi = km.items.new('object.hide_view_clear', 'H', 'PRESS', alt=True)
|
||||
kmi = km.items.new('object.hide_view_set', 'H', 'PRESS')
|
||||
kmi = km.items.new('object.hide_view_set', 'H', 'PRESS', shift=True)
|
||||
kmi.properties.unselected = True
|
||||
kmi = km.items.add('object.move_to_layer', 'M', 'PRESS')
|
||||
kmi = km.items.add('object.delete', 'X', 'PRESS')
|
||||
kmi = km.items.add('object.delete', 'DEL', 'PRESS')
|
||||
kmi = km.items.add('wm.call_menu', 'A', 'PRESS', shift=True)
|
||||
kmi = km.items.new('object.move_to_layer', 'M', 'PRESS')
|
||||
kmi = km.items.new('object.delete', 'X', 'PRESS')
|
||||
kmi = km.items.new('object.delete', 'DEL', 'PRESS')
|
||||
kmi = km.items.new('wm.call_menu', 'A', 'PRESS', shift=True)
|
||||
kmi.properties.name = 'INFO_MT_add'
|
||||
kmi = km.items.add('object.duplicates_make_real', 'A', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.add('wm.call_menu', 'A', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.duplicates_make_real', 'A', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('wm.call_menu', 'A', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_object_apply'
|
||||
kmi = km.items.add('wm.call_menu', 'U', 'PRESS')
|
||||
kmi = km.items.new('wm.call_menu', 'U', 'PRESS')
|
||||
kmi.properties.name = 'VIEW3D_MT_make_single_user'
|
||||
kmi = km.items.add('wm.call_menu', 'L', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('wm.call_menu', 'L', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_make_links'
|
||||
kmi = km.items.add('object.duplicate_move', 'D', 'PRESS', shift=True)
|
||||
kmi = km.items.add('object.duplicate_move_linked', 'D', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.join', 'J', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('object.convert', 'C', 'PRESS', alt=True)
|
||||
kmi = km.items.add('object.proxy_make', 'P', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.add('object.make_local', 'L', 'PRESS')
|
||||
kmi = km.items.add('anim.keyframe_insert_menu', 'I', 'PRESS')
|
||||
kmi = km.items.add('anim.keyframe_delete_v3d', 'I', 'PRESS', alt=True)
|
||||
kmi = km.items.add('anim.keying_set_active_set', 'I', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi = km.items.add('group.create', 'G', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('group.objects_remove', 'G', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.add('group.objects_add_active', 'G', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.add('group.objects_remove_active', 'G', 'PRESS', shift=True, alt=True)
|
||||
kmi = km.items.add('wm.call_menu', 'W', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.duplicate_move', 'D', 'PRESS', shift=True)
|
||||
kmi = km.items.new('object.duplicate_move_linked', 'D', 'PRESS', alt=True)
|
||||
kmi = km.items.new('object.join', 'J', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.convert', 'C', 'PRESS', alt=True)
|
||||
kmi = km.items.new('object.proxy_make', 'P', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.new('object.make_local', 'L', 'PRESS')
|
||||
kmi = km.items.new('anim.keyframe_insert_menu', 'I', 'PRESS')
|
||||
kmi = km.items.new('anim.keyframe_delete_v3d', 'I', 'PRESS', alt=True)
|
||||
kmi = km.items.new('anim.keying_set_active_set', 'I', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi = km.items.new('group.create', 'G', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('group.objects_remove', 'G', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.new('group.objects_add_active', 'G', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('group.objects_remove_active', 'G', 'PRESS', shift=True, alt=True)
|
||||
kmi = km.items.new('wm.call_menu', 'W', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_object_specials'
|
||||
kmi = km.items.add('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True)
|
||||
kmi.properties.level = 0
|
||||
kmi = km.items.add('object.subdivision_set', 'ONE', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.subdivision_set', 'ONE', 'PRESS', ctrl=True)
|
||||
kmi.properties.level = 1
|
||||
kmi = km.items.add('object.subdivision_set', 'TWO', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.subdivision_set', 'TWO', 'PRESS', ctrl=True)
|
||||
kmi.properties.level = 2
|
||||
kmi = km.items.add('object.subdivision_set', 'THREE', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.subdivision_set', 'THREE', 'PRESS', ctrl=True)
|
||||
kmi.properties.level = 3
|
||||
kmi = km.items.add('object.subdivision_set', 'FOUR', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.subdivision_set', 'FOUR', 'PRESS', ctrl=True)
|
||||
kmi.properties.level = 4
|
||||
kmi = km.items.add('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True)
|
||||
kmi.properties.level = 5
|
||||
kmi = km.items.add('object.select_all', 'SELECTMOUSE', 'CLICK')
|
||||
kmi = km.items.new('object.select_all', 'SELECTMOUSE', 'CLICK')
|
||||
kmi.properties.action = 'DESELECT'
|
||||
|
||||
# Map Mesh
|
||||
km = kc.add_keymap('Mesh', space_type='EMPTY', region_type='WINDOW', modal=False)
|
||||
km = kc.keymaps.new('Mesh', space_type='EMPTY', region_type='WINDOW', modal=False)
|
||||
|
||||
kmi = km.items.add('mesh.loopcut_slide', 'R', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('mesh.loop_select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.add('mesh.loop_select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
|
||||
kmi = km.items.new('mesh.loopcut_slide', 'R', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('mesh.loop_select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.new('mesh.loop_select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
|
||||
kmi.properties.extend = True
|
||||
kmi = km.items.add('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.add('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi = km.items.new('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.new('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi.properties.extend = True
|
||||
kmi = km.items.add('mesh.select_shortest_path', 'SELECTMOUSE', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('mesh.select_all', 'A', 'PRESS')
|
||||
kmi = km.items.add('mesh.select_more', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('mesh.select_less', 'NUMPAD_MINUS', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('mesh.select_inverse', 'I', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('mesh.select_non_manifold', 'M', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi = km.items.add('mesh.select_linked', 'L', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('mesh.select_linked_pick', 'L', 'PRESS')
|
||||
kmi = km.items.add('mesh.select_linked_pick', 'L', 'PRESS', shift=True)
|
||||
kmi = km.items.new('mesh.select_shortest_path', 'SELECTMOUSE', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('mesh.select_all', 'A', 'PRESS')
|
||||
kmi = km.items.new('mesh.select_more', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('mesh.select_less', 'NUMPAD_MINUS', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('mesh.select_inverse', 'I', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('mesh.select_non_manifold', 'M', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi = km.items.new('mesh.select_linked', 'L', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('mesh.select_linked_pick', 'L', 'PRESS')
|
||||
kmi = km.items.new('mesh.select_linked_pick', 'L', 'PRESS', shift=True)
|
||||
kmi.properties.deselect = True
|
||||
kmi = km.items.add('mesh.faces_select_linked_flat', 'F', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi = km.items.new('mesh.faces_select_linked_flat', 'F', 'PRESS', shift=True, ctrl=True, alt=True)
|
||||
kmi.properties.sharpness = 135.0
|
||||
kmi = km.items.add('mesh.select_similar', 'G', 'PRESS', shift=True)
|
||||
kmi = km.items.add('wm.call_menu', 'TAB', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('mesh.select_similar', 'G', 'PRESS', shift=True)
|
||||
kmi = km.items.new('wm.call_menu', 'TAB', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_selection_mode'
|
||||
kmi = km.items.add('mesh.hide', 'H', 'PRESS')
|
||||
kmi = km.items.add('mesh.hide', 'H', 'PRESS', shift=True)
|
||||
kmi = km.items.new('mesh.hide', 'H', 'PRESS')
|
||||
kmi = km.items.new('mesh.hide', 'H', 'PRESS', shift=True)
|
||||
kmi.properties.unselected = True
|
||||
kmi = km.items.add('mesh.reveal', 'H', 'PRESS', alt=True)
|
||||
kmi = km.items.add('mesh.normals_make_consistent', 'N', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('mesh.normals_make_consistent', 'N', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('mesh.reveal', 'H', 'PRESS', alt=True)
|
||||
kmi = km.items.new('mesh.normals_make_consistent', 'N', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('mesh.normals_make_consistent', 'N', 'PRESS', shift=True, ctrl=True)
|
||||
kmi.properties.inside = True
|
||||
kmi = km.items.add('view3d.edit_mesh_extrude_move_normal', 'E', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('view3d.edit_mesh_extrude_individual_move', 'E', 'PRESS', shift=True)
|
||||
kmi = km.items.add('wm.call_menu', 'E', 'PRESS', alt=True)
|
||||
kmi = km.items.new('view3d.edit_mesh_extrude_move_normal', 'E', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('view3d.edit_mesh_extrude_individual_move', 'E', 'PRESS', shift=True)
|
||||
kmi = km.items.new('wm.call_menu', 'E', 'PRESS', alt=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_extrude'
|
||||
kmi = km.items.add('mesh.spin', 'R', 'PRESS', alt=True)
|
||||
kmi = km.items.add('mesh.fill', 'F', 'PRESS', alt=True)
|
||||
kmi = km.items.add('mesh.beautify_fill', 'F', 'PRESS', shift=True, alt=True)
|
||||
kmi = km.items.add('mesh.quads_convert_to_tris', 'T', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('mesh.tris_convert_to_quads', 'J', 'PRESS', alt=True)
|
||||
kmi = km.items.add('mesh.edge_flip', 'F', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.add('mesh.rip_move', 'V', 'PRESS')
|
||||
kmi = km.items.add('mesh.merge', 'M', 'PRESS', alt=True)
|
||||
kmi = km.items.add('transform.shrink_fatten', 'S', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.add('mesh.edge_face_add', 'F', 'PRESS')
|
||||
kmi = km.items.add('mesh.duplicate_move', 'D', 'PRESS', shift=True)
|
||||
kmi = km.items.add('wm.call_menu', 'A', 'PRESS', shift=True)
|
||||
kmi = km.items.new('mesh.spin', 'R', 'PRESS', alt=True)
|
||||
kmi = km.items.new('mesh.fill', 'F', 'PRESS', alt=True)
|
||||
kmi = km.items.new('mesh.beautify_fill', 'F', 'PRESS', shift=True, alt=True)
|
||||
kmi = km.items.new('mesh.quads_convert_to_tris', 'T', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('mesh.tris_convert_to_quads', 'J', 'PRESS', alt=True)
|
||||
kmi = km.items.new('mesh.edge_flip', 'F', 'PRESS', shift=True, ctrl=True)
|
||||
kmi = km.items.new('mesh.rip_move', 'V', 'PRESS')
|
||||
kmi = km.items.new('mesh.merge', 'M', 'PRESS', alt=True)
|
||||
kmi = km.items.new('transform.shrink_fatten', 'S', 'PRESS', ctrl=True, alt=True)
|
||||
kmi = km.items.new('mesh.edge_face_add', 'F', 'PRESS')
|
||||
kmi = km.items.new('mesh.duplicate_move', 'D', 'PRESS', shift=True)
|
||||
kmi = km.items.new('wm.call_menu', 'A', 'PRESS', shift=True)
|
||||
kmi.properties.name = 'INFO_MT_mesh_add'
|
||||
kmi = km.items.add('mesh.separate', 'P', 'PRESS')
|
||||
kmi = km.items.add('mesh.split', 'Y', 'PRESS')
|
||||
kmi = km.items.add('mesh.dupli_extrude_cursor', 'ACTIONMOUSE', 'CLICK', ctrl=True)
|
||||
kmi = km.items.add('mesh.delete', 'X', 'PRESS')
|
||||
kmi = km.items.add('mesh.delete', 'DEL', 'PRESS')
|
||||
kmi = km.items.add('mesh.knife_cut', 'LEFTMOUSE', 'PRESS', key_modifier='K')
|
||||
kmi = km.items.add('mesh.knife_cut', 'LEFTMOUSE', 'PRESS', shift=True, key_modifier='K')
|
||||
kmi = km.items.new('mesh.separate', 'P', 'PRESS')
|
||||
kmi = km.items.new('mesh.split', 'Y', 'PRESS')
|
||||
kmi = km.items.new('mesh.dupli_extrude_cursor', 'ACTIONMOUSE', 'CLICK', ctrl=True)
|
||||
kmi = km.items.new('mesh.delete', 'X', 'PRESS')
|
||||
kmi = km.items.new('mesh.delete', 'DEL', 'PRESS')
|
||||
kmi = km.items.new('mesh.knife_cut', 'LEFTMOUSE', 'PRESS', key_modifier='K')
|
||||
kmi = km.items.new('mesh.knife_cut', 'LEFTMOUSE', 'PRESS', shift=True, key_modifier='K')
|
||||
kmi.properties.type = 'MIDPOINTS'
|
||||
kmi = km.items.add('object.vertex_parent_set', 'P', 'PRESS', ctrl=True)
|
||||
kmi = km.items.add('wm.call_menu', 'W', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('object.vertex_parent_set', 'P', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('wm.call_menu', 'W', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_specials'
|
||||
kmi = km.items.add('wm.call_menu', 'F', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('wm.call_menu', 'F', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_faces'
|
||||
kmi = km.items.add('wm.call_menu', 'E', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('wm.call_menu', 'E', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_edges'
|
||||
kmi = km.items.add('wm.call_menu', 'V', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('wm.call_menu', 'V', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_edit_mesh_vertices'
|
||||
kmi = km.items.add('wm.call_menu', 'H', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('wm.call_menu', 'H', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_hook'
|
||||
kmi = km.items.add('wm.call_menu', 'U', 'PRESS')
|
||||
kmi = km.items.new('wm.call_menu', 'U', 'PRESS')
|
||||
kmi.properties.name = 'VIEW3D_MT_uv_map'
|
||||
kmi = km.items.add('wm.call_menu', 'G', 'PRESS', ctrl=True)
|
||||
kmi = km.items.new('wm.call_menu', 'G', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = 'VIEW3D_MT_vertex_group'
|
||||
kmi = km.items.add('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
|
||||
kmi = km.items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
|
||||
kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
|
||||
kmi = km.items.add('wm.context_toggle_enum', 'O', 'PRESS')
|
||||
kmi = km.items.new('wm.context_toggle_enum', 'O', 'PRESS')
|
||||
kmi.properties.data_path = 'tool_settings.proportional_edit'
|
||||
kmi.properties.value_1 = 'DISABLED'
|
||||
kmi.properties.value_2 = 'ENABLED'
|
||||
kmi = km.items.add('wm.context_toggle_enum', 'O', 'PRESS', alt=True)
|
||||
kmi = km.items.new('wm.context_toggle_enum', 'O', 'PRESS', alt=True)
|
||||
kmi.properties.data_path = 'tool_settings.proportional_edit'
|
||||
kmi.properties.value_1 = 'DISABLED'
|
||||
kmi.properties.value_2 = 'CONNECTED'
|
||||
kmi = km.items.add('mesh.select_all', 'SELECTMOUSE', 'CLICK')
|
||||
kmi = km.items.new('mesh.select_all', 'SELECTMOUSE', 'CLICK')
|
||||
kmi.properties.action = 'DESELECT'
|
||||
|
||||
wm.active_keyconfig = kc
|
||||
wm.keyconfigs.active = kc
|
||||
|
||||
bpy.context.user_preferences.edit.use_drag_immediately = True
|
||||
bpy.context.user_preferences.edit.use_insertkey_xyz_to_rgb = False
|
||||
|
@ -38,7 +38,7 @@ class ExportSomeData(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
wm = context.manager
|
||||
wm = context.window_manager
|
||||
|
||||
if True:
|
||||
# File selector
|
||||
|
@ -25,7 +25,7 @@ class ModalOperator(bpy.types.Operator):
|
||||
|
||||
def invoke(self, context, event):
|
||||
if context.object:
|
||||
context.manager.add_modal_handler(self)
|
||||
context.window_manager.add_modal_handler(self)
|
||||
self.properties.first_mouse_x = event.mouse_x
|
||||
self.properties.first_value = context.object.location.x
|
||||
return {'RUNNING_MODAL'}
|
||||
|
@ -52,7 +52,7 @@ class ModalDrawOperator(bpy.types.Operator):
|
||||
|
||||
def invoke(self, context, event):
|
||||
if context.area.type == 'VIEW_3D':
|
||||
context.manager.add_modal_handler(self)
|
||||
context.window_manager.add_modal_handler(self)
|
||||
|
||||
# Add the region OpenGL drawing callback
|
||||
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
|
||||
|
@ -39,7 +39,7 @@ class ViewOperator(bpy.types.Operator):
|
||||
v3d = context.space_data
|
||||
rv3d = v3d.region_3d
|
||||
|
||||
context.manager.add_modal_handler(self)
|
||||
context.window_manager.add_modal_handler(self)
|
||||
|
||||
if rv3d.view_perspective == 'CAMERA':
|
||||
rv3d.view_perspective = 'PERSP'
|
||||
|
@ -9,11 +9,11 @@ def main(context):
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
|
||||
if not mesh.active_uv_texture:
|
||||
bpy.ops.mesh.uv_texture_add()
|
||||
if not mesh.uv_textures:
|
||||
uvtex = bpy.ops.mesh.uv_texture_add()
|
||||
|
||||
# adjust UVs
|
||||
for i, uv in enumerate(mesh.active_uv_texture.data):
|
||||
for i, uv in enumerate(uvtex.data):
|
||||
uvs = uv.uv1, uv.uv2, uv.uv3, uv.uv4
|
||||
for j, v_idx in enumerate(mesh.faces[i].vertices):
|
||||
if uv.select_uv[j]:
|
||||
|
@ -27,7 +27,7 @@ class MotionPathButtonsPanel():
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_label = "Motion Paths"
|
||||
bl_default_closed = True
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_settings(self, context, avs, bones=False):
|
||||
layout = self.layout
|
||||
@ -65,7 +65,7 @@ class OnionSkinButtonsPanel():
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_label = "Onion Skinning"
|
||||
bl_default_closed = True
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -33,7 +33,7 @@ class ArmatureButtonsPanel():
|
||||
|
||||
class DATA_PT_context_arm(ArmatureButtonsPanel, bpy.types.Panel):
|
||||
bl_label = ""
|
||||
bl_show_header = False
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -119,14 +119,14 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, bpy.types.Panel):
|
||||
pose = ob.pose
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(pose, "bone_groups", pose, "active_bone_group_index", rows=2)
|
||||
row.template_list(pose, "bone_groups", pose.bone_groups, "active_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.active = (ob.proxy is None)
|
||||
col.operator("pose.group_add", icon='ZOOMIN', text="")
|
||||
col.operator("pose.group_remove", icon='ZOOMOUT', text="")
|
||||
|
||||
group = pose.active_bone_group
|
||||
group = pose.bone_groups.active
|
||||
if group:
|
||||
col = layout.column()
|
||||
col.active = (ob.proxy is None)
|
||||
@ -139,7 +139,10 @@ class DATA_PT_bone_groups(ArmatureButtonsPanel, bpy.types.Panel):
|
||||
col.prop(group, "color_set")
|
||||
if group.color_set:
|
||||
col = split.column()
|
||||
col.template_triColorSet(group, "colors")
|
||||
subrow = col.row(align=True)
|
||||
subrow.prop(group.colors, "normal", text="")
|
||||
subrow.prop(group.colors, "select", text="")
|
||||
subrow.prop(group.colors, "active", text="")
|
||||
|
||||
row = layout.row()
|
||||
row.active = (ob.proxy is None)
|
||||
@ -184,7 +187,7 @@ class DATA_PT_ghost(ArmatureButtonsPanel, bpy.types.Panel):
|
||||
|
||||
class DATA_PT_iksolver_itasc(ArmatureButtonsPanel, bpy.types.Panel):
|
||||
bl_label = "iTaSC parameters"
|
||||
bl_default_closed = True
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@ -38,7 +38,7 @@ class DATA_PT_template(bpy.types.Panel):
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "data"
|
||||
bl_default_closed = True
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
templates = []
|
||||
|
||||
@ -250,7 +250,7 @@ class AsScript(bpy.types.Operator):
|
||||
import os
|
||||
obj = context.object
|
||||
self.properties.filepath = os.path.splitext(bpy.data.filepath)[0] + "-" + bpy.path.clean_name(obj.name) + ".py"
|
||||
wm = context.manager
|
||||
wm = context.window_manager
|
||||
wm.add_fileselect(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
|
@ -33,7 +33,7 @@ class BoneButtonsPanel():
|
||||
|
||||
class BONE_PT_context_bone(BoneButtonsPanel, bpy.types.Panel):
|
||||
bl_label = ""
|
||||
bl_show_header = False
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -95,7 +95,7 @@ class BONE_PT_transform(BoneButtonsPanel, bpy.types.Panel):
|
||||
|
||||
class BONE_PT_transform_locks(BoneButtonsPanel, bpy.types.Panel):
|
||||
bl_label = "Transform Locks"
|
||||
bl_default_closed = True
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@ -151,14 +151,14 @@ class BONE_PT_relations(BoneButtonsPanel, bpy.types.Panel):
|
||||
|
||||
if ob and pchan:
|
||||
col.label(text="Bone Group:")
|
||||
col.prop_object(pchan, "bone_group", ob.pose, "bone_groups", text="")
|
||||
col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Parent:")
|
||||
if context.bone:
|
||||
col.prop(bone, "parent", text="")
|
||||
else:
|
||||
col.prop_object(bone, "parent", arm, "edit_bones", text="")
|
||||
col.prop_search(bone, "parent", arm, "edit_bones", text="")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = (bone.parent is not None)
|
||||
@ -202,12 +202,12 @@ class BONE_PT_display(BoneButtonsPanel, bpy.types.Panel):
|
||||
col.label(text="Custom Shape:")
|
||||
col.prop(pchan, "custom_shape", text="")
|
||||
if pchan.custom_shape:
|
||||
col.prop_object(pchan, "custom_shape_transform", ob.pose, "bones", text="At")
|
||||
col.prop_search(pchan, "custom_shape_transform", ob.pose, "bones", text="At")
|
||||
|
||||
|
||||
class BONE_PT_inverse_kinematics(BoneButtonsPanel, bpy.types.Panel):
|
||||
bl_label = "Inverse Kinematics"
|
||||
bl_default_closed = True
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@ -224,7 +224,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, bpy.types.Panel):
|
||||
row.prop(ob.pose, "ik_solver")
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
split.prop(pchan, "lock_ik_x", text="Lock X")
|
||||
split.prop(pchan, "lock_ik_x", icon='LOCKED' if pchan.lock_ik_x else 'UNLOCKED', text="X")
|
||||
split.active = pchan.is_in_ik_chain
|
||||
row = split.row()
|
||||
row.prop(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
|
||||
@ -241,8 +241,8 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, bpy.types.Panel):
|
||||
sub.active = pchan.lock_ik_x == False and pchan.use_ik_limit_x and pchan.is_in_ik_chain
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
split.prop(pchan, "lock_ik_y", text="Y")
|
||||
split.active = pchan.is_in_ik_chain and pchan.is_in_ik_chain
|
||||
split.prop(pchan, "lock_ik_y", icon='LOCKED' if pchan.lock_ik_y else 'UNLOCKED', text="Y")
|
||||
split.active = pchan.is_in_ik_chain
|
||||
row = split.row()
|
||||
row.prop(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
|
||||
row.active = pchan.lock_ik_y == False and pchan.is_in_ik_chain
|
||||
@ -259,8 +259,8 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, bpy.types.Panel):
|
||||
sub.active = pchan.lock_ik_y == False and pchan.use_ik_limit_y and pchan.is_in_ik_chain
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
split.prop(pchan, "lock_ik_z", text="Z")
|
||||
split.active = pchan.is_in_ik_chain and pchan.is_in_ik_chain
|
||||
split.prop(pchan, "lock_ik_z", icon='LOCKED' if pchan.lock_ik_z else 'UNLOCKED', text="Z")
|
||||
split.active = pchan.is_in_ik_chain
|
||||
sub = split.row()
|
||||
sub.prop(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
|
||||
sub.active = pchan.lock_ik_z == False and pchan.is_in_ik_chain
|
||||
@ -274,10 +274,12 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, bpy.types.Panel):
|
||||
sub.prop(pchan, "ik_min_z", text="")
|
||||
sub.prop(pchan, "ik_max_z", text="")
|
||||
sub.active = pchan.lock_ik_z == False and pchan.use_ik_limit_z and pchan.is_in_ik_chain
|
||||
split = layout.split()
|
||||
split.prop(pchan, "ik_stretch", text="Stretch", slider=True)
|
||||
split.label()
|
||||
split.active = pchan.is_in_ik_chain
|
||||
|
||||
split = layout.split(percentage=0.25)
|
||||
split.label(text="Stretch:")
|
||||
sub = split.row()
|
||||
sub.prop(pchan, "ik_stretch", text="", slider=True)
|
||||
sub.active = pchan.is_in_ik_chain
|
||||
|
||||
if ob.pose.ik_solver == 'ITASC':
|
||||
split = layout.split()
|
||||
@ -295,7 +297,7 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, bpy.types.Panel):
|
||||
|
||||
class BONE_PT_deform(BoneButtonsPanel, bpy.types.Panel):
|
||||
bl_label = "Deform"
|
||||
bl_default_closed = True
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_header(self, context):
|
||||
bone = context.bone
|
||||
|
@ -34,7 +34,7 @@ class CameraButtonsPanel():
|
||||
|
||||
class DATA_PT_context_camera(CameraButtonsPanel, bpy.types.Panel):
|
||||
bl_label = ""
|
||||
bl_show_header = False
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -50,7 +50,7 @@ class CurveButtonsPanelActive(CurveButtonsPanel):
|
||||
|
||||
class DATA_PT_context_curve(CurveButtonsPanel, bpy.types.Panel):
|
||||
bl_label = ""
|
||||
bl_show_header = False
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@ -42,7 +42,7 @@ class DataButtonsPanel():
|
||||
|
||||
class DATA_PT_context_lamp(DataButtonsPanel, bpy.types.Panel):
|
||||
bl_label = ""
|
||||
bl_show_header = False
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
|
||||
def draw(self, context):
|
||||
@ -54,13 +54,15 @@ class DATA_PT_context_lamp(DataButtonsPanel, bpy.types.Panel):
|
||||
|
||||
split = layout.split(percentage=0.65)
|
||||
|
||||
texture_count = len(lamp.texture_slots.keys())
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "data")
|
||||
split.separator()
|
||||
elif lamp:
|
||||
split.template_ID(space, "pin_id")
|
||||
split.separator()
|
||||
|
||||
if texture_count != 0:
|
||||
split.label(text=str(texture_count), icon='TEXTURE')
|
||||
|
||||
class DATA_PT_preview(DataButtonsPanel, bpy.types.Panel):
|
||||
bl_label = "Preview"
|
||||
@ -367,7 +369,7 @@ class DATA_PT_spot(DataButtonsPanel, bpy.types.Panel):
|
||||
|
||||
class DATA_PT_falloff_curve(DataButtonsPanel, bpy.types.Panel):
|
||||
bl_label = "Falloff Curve"
|
||||
bl_default_closed = True
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
|
||||
@classmethod
|
||||
|
@ -33,7 +33,7 @@ class DataButtonsPanel():
|
||||
|
||||
class DATA_PT_context_lattice(DataButtonsPanel, bpy.types.Panel):
|
||||
bl_label = ""
|
||||
bl_show_header = False
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -79,7 +79,7 @@ class DATA_PT_lattice(DataButtonsPanel, bpy.types.Panel):
|
||||
|
||||
row = layout.row()
|
||||
row.prop(lat, "use_outside")
|
||||
row.prop_object(lat, "vertex_group", context.object, "vertex_groups", text="")
|
||||
row.prop_search(lat, "vertex_group", context.object, "vertex_groups", text="")
|
||||
|
||||
|
||||
class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel, bpy.types.Panel):
|
||||
|
@ -60,7 +60,7 @@ class MeshButtonsPanel():
|
||||
|
||||
class DATA_PT_context_mesh(MeshButtonsPanel, bpy.types.Panel):
|
||||
bl_label = ""
|
||||
bl_show_header = False
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
|
||||
def draw(self, context):
|
||||
@ -127,14 +127,14 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, bpy.types.Panel):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.object
|
||||
group = ob.active_vertex_group
|
||||
group = ob.vertex_groups.active
|
||||
|
||||
rows = 2
|
||||
if group:
|
||||
rows = 5
|
||||
|
||||
row = layout.row()
|
||||
row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index", rows=rows)
|
||||
row.template_list(ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.operator("object.vertex_group_add", icon='ZOOMIN', text="")
|
||||
@ -245,8 +245,8 @@ class DATA_PT_shape_keys(MeshButtonsPanel, bpy.types.Panel):
|
||||
col = split.column(align=True)
|
||||
col.active = enable_edit_value
|
||||
col.label(text="Blend:")
|
||||
col.prop_object(kb, "vertex_group", ob, "vertex_groups", text="")
|
||||
col.prop_object(kb, "relative_key", key, "keys", text="")
|
||||
col.prop_search(kb, "vertex_group", ob, "vertex_groups", text="")
|
||||
col.prop_search(kb, "relative_key", key, "keys", text="")
|
||||
|
||||
else:
|
||||
row = layout.row()
|
||||
@ -266,13 +266,13 @@ class DATA_PT_uv_texture(MeshButtonsPanel, bpy.types.Panel):
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
|
||||
col.template_list(me, "uv_textures", me, "active_uv_texture_index", rows=2)
|
||||
col.template_list(me, "uv_textures", me.uv_textures, "active_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.operator("mesh.uv_texture_add", icon='ZOOMIN', text="")
|
||||
col.operator("mesh.uv_texture_remove", icon='ZOOMOUT', text="")
|
||||
|
||||
lay = me.active_uv_texture
|
||||
lay = me.uv_textures.active
|
||||
if lay:
|
||||
layout.prop(lay, "name")
|
||||
|
||||
@ -300,7 +300,7 @@ class DATA_PT_texface(MeshButtonsPanel, bpy.types.Panel):
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
|
||||
col.prop(tf, "use_bitmap_text")
|
||||
col.prop(tf, "use_image")
|
||||
col.prop(tf, "use_light")
|
||||
col.prop(tf, "hide")
|
||||
col.prop(tf, "use_collision")
|
||||
@ -335,13 +335,13 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, bpy.types.Panel):
|
||||
row = layout.row()
|
||||
col = row.column()
|
||||
|
||||
col.template_list(me, "vertex_colors", me, "active_vertex_color_index", rows=2)
|
||||
col.template_list(me, "vertex_colors", me.vertex_colors, "active_index", rows=2)
|
||||
|
||||
col = row.column(align=True)
|
||||
col.operator("mesh.vertex_color_add", icon='ZOOMIN', text="")
|
||||
col.operator("mesh.vertex_color_remove", icon='ZOOMOUT', text="")
|
||||
|
||||
lay = me.active_vertex_color
|
||||
lay = me.vertex_colors.active
|
||||
if lay:
|
||||
layout.prop(lay, "name")
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user