added 'bintoc' tool; embedded blender python scripts

This commit is contained in:
Jack Andersen 2015-08-04 11:37:12 -10:00
parent 5bc474d2c5
commit 31aa40cc77
10 changed files with 156 additions and 13 deletions

View File

@ -12,6 +12,7 @@ set(LOG_VISOR_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern/LogVisor/include)
set(ANGELSCRIPT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern/AngelScript/angelscript/include)
set(SQUISH_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern/libSquish)
add_definitions(-DAS_USE_NAMESPACE=1 -DAS_NO_EXCEPTIONS=1)
add_subdirectory(bintoc)
add_subdirectory(extern)
include_directories(include ${LOG_VISOR_INCLUDE_DIR} ${ATHENA_INCLUDE_DIR} ${ANGELSCRIPT_INCLUDE_DIR})
add_subdirectory(lib)

View File

@ -0,0 +1,6 @@
add_executable(bintoc bintoc.c)
macro(bintoc out in sym)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${out}
COMMAND $<TARGET_FILE:bintoc> ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${in} ${CMAKE_CURRENT_BINARY_DIR}/${out} ${sym}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${in})
endmacro()

39
hecl/bintoc/bintoc.c Normal file
View File

@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdint.h>
int main(int argc, char** argv)
{
if (argc < 4)
{
fprintf(stderr, "Usage: bintoc <in> <out> <symbol>\n");
return 1;
}
FILE* fin = fopen(argv[1], "rb");
if (!fin)
{
fprintf(stderr, "Unable to open %s for reading\n", argv[1]);
return 1;
}
FILE* fout = fopen(argv[2], "wb");
if (!fout)
{
fprintf(stderr, "Unable to open %s for writing\n", argv[2]);
return 1;
}
fprintf(fout, "#include <stdint.h>\n#include <stdlib.h>\nconst uint8_t %s[] =\n{\n", argv[3]);
size_t totalSz = 0;
size_t readSz;
uint8_t buf[32];
while ((readSz = fread(buf, 1, 32, fin)))
{
fprintf(fout, " ");
totalSz += readSz;
for (int b=0 ; b<readSz ; ++b)
fprintf(fout, "0x%02X, ", buf[b]);
fprintf(fout, "\n");
}
fprintf(fout, "0x0};\nconst size_t %s_SZ = %zu;\n", argv[3], totalSz);
fclose(fin);
fclose(fout);
return 0;
}

View File

@ -23,7 +23,8 @@ BlenderConnection* SharedBlenderConnection = nullptr;
#define DEFAULT_BLENDER_BIN "blender"
#endif
#define TEMP_SHELLSCRIPT "/home/jacko/hecl/blender/blendershell.py"
extern "C" uint8_t BLENDERSHELL[];
extern "C" size_t BLENDERSHELL_SZ;
size_t BlenderConnection::_readLine(char* buf, size_t bufSz)
{
@ -136,6 +137,24 @@ void BlenderConnection::_closePipe()
BlenderConnection::BlenderConnection(bool silenceBlender)
{
/* Put blendershell.py in temp dir */
#ifdef _WIN32
wchar_t* TMPDIR = _wgetenv(L"TEMP");
if (!TMPDIR)
TMPDIR = (wchar_t*)L"\\Temp";
#else
char* TMPDIR = getenv("TMPDIR");
if (!TMPDIR)
TMPDIR = (char*)"/tmp";
#endif
HECL::SystemString blenderShellPath(TMPDIR);
blenderShellPath += _S("/blendershell.py");
FILE* fp = HECL::Fopen(blenderShellPath.c_str(), _S("w"));
if (!fp)
BlenderLog.report(LogVisor::FatalError, _S("unable to open %s for writing"), blenderShellPath.c_str());
fwrite(BLENDERSHELL, 1, BLENDERSHELL_SZ, fp);
fclose(fp);
/* Construct communication pipes */
#if _WIN32
SECURITY_ATTRIBUTES sattrs = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
@ -224,7 +243,7 @@ BlenderConnection::BlenderConnection(bool silenceBlender)
if (blenderBin)
{
execlp(blenderBin, blenderBin,
"--background", "-P", TEMP_SHELLSCRIPT,
"--background", "-P", blenderShellPath.c_str(),
"--", readfds, writefds, NULL);
if (errno != ENOENT)
{
@ -236,7 +255,7 @@ BlenderConnection::BlenderConnection(bool silenceBlender)
/* Otherwise default blender */
execlp(DEFAULT_BLENDER_BIN, DEFAULT_BLENDER_BIN,
"--background", "-P", TEMP_SHELLSCRIPT,
"--background", "-P", blenderShellPath.c_str(),
"--", readfds, writefds, NULL);
if (errno != ENOENT)
{
@ -294,12 +313,13 @@ BlenderConnection::~BlenderConnection()
bool BlenderConnection::createBlend(const SystemString& path)
{
_writeLine(("CREATE \"" + path + "\"").c_str());
HECL::SystemUTF8View pathView(path);
_writeLine(("CREATE \"" + pathView.str() + "\"").c_str());
char lineBuf[256];
_readLine(lineBuf, sizeof(lineBuf));
if (!strcmp(lineBuf, "FINISHED"))
{
m_loadedBlend = path;
m_loadedBlend = pathView.str();
return true;
}
return false;
@ -307,17 +327,51 @@ bool BlenderConnection::createBlend(const SystemString& path)
bool BlenderConnection::openBlend(const SystemString& path)
{
_writeLine(("OPEN \"" + path + "\"").c_str());
HECL::SystemUTF8View pathView(path);
_writeLine(("OPEN \"" + pathView.str() + "\"").c_str());
char lineBuf[256];
_readLine(lineBuf, sizeof(lineBuf));
if (!strcmp(lineBuf, "FINISHED"))
{
m_loadedBlend = path;
m_loadedBlend = pathView.str();
return true;
}
return false;
}
bool BlenderConnection::saveBlend()
{
_writeLine("SAVE");
char lineBuf[256];
_readLine(lineBuf, sizeof(lineBuf));
if (!strcmp(lineBuf, "FINISHED"))
return true;
return false;
}
void BlenderConnection::PyOutStream::linkBlend(const SystemString& relPath, const std::string& objName,
bool link)
{
HECL::SystemUTF8View relView(relPath);
format("if '%s' not in bpy.data.scenes:\n"
" with bpy.data.libraries.load('//%s', link=%s, relative=True) as (data_from, data_to):\n"
" data_to.scenes = data_from.scenes\n"
" obj_scene = None\n"
" for scene in data_to.scenes:\n"
" if scene.name == '%s':\n"
" obj_scene = scene\n"
" break\n"
" obj = None\n"
" for object in obj_scene.objects:\n"
" if object.name == obj_scene.name:\n"
" obj = object\n"
"else:\n"
" obj = bpy.data.objects['%s']\n"
"\n",
objName.c_str(), relView.str().c_str(), link?"True":"False",
objName.c_str(), objName.c_str());
}
bool BlenderConnection::cookBlend(std::function<char*(uint32_t)> bufGetter,
const std::string& expectedType,
const std::string& platform,

View File

@ -46,6 +46,7 @@ public:
bool createBlend(const SystemString& path);
bool openBlend(const SystemString& path);
bool saveBlend();
enum CookPlatform
{
CP_MODERN = 0,
@ -120,6 +121,7 @@ public:
free(result);
va_end(ap);
}
void linkBlend(const SystemString& target, const std::string& objName, bool link=true);
};
inline PyOutStream beginPythonOut()
{

View File

@ -11,8 +11,11 @@ list(APPEND PY_SOURCES
addon/sact/SACTEvent.py
addon/sact/SACTSubtype.py)
bintoc(blendershell.c blendershell.py BLENDERSHELL)
add_library(HECLBlender
BlenderConnection.cpp
BlenderConnection.hpp
blendershell.py
blendershell.c
${PY_SOURCES})

View File

@ -1,4 +1,4 @@
import bpy, sys, os, re
import bpy, sys, os, re, code
ARGS_PATTERN = re.compile(r'''(?:"([^"]+)"|'([^']+)'|(\S+))''')
@ -71,18 +71,43 @@ while True:
else:
writepipeline(b'CANCELLED')
elif cmdargs[0] == 'SAVE':
bpy.context.user_preferences.filepaths.save_version = 0
if 'FINISHED' in bpy.ops.wm.save_mainfile(check_existing=False):
writepipeline(b'FINISHED')
else:
writepipeline(b'CANCELLED')
elif cmdargs[0] == 'PYBEGIN':
writepipeline(b'READY')
globals = dict()
locals = dict()
compbuf = str()
prev_leading_spaces = 0
while True:
try:
line = readpipeline()
if line == b'PYEND':
writepipeline(b'DONE')
break
co = compile(line+b'\n', '<HECL>', 'single')
exec(co, globals, locals)
linestr = line.decode()
if linestr.isspace() or not len(linestr):
writepipeline(b'OK')
continue
leading_spaces = len(linestr) - len(linestr.lstrip())
if prev_leading_spaces and not leading_spaces:
compbuf += '\n'
co = code.compile_command(compbuf, filename='<HECL>')
if co is not None:
exec(co, globals)
compbuf = str()
prev_leading_spaces = leading_spaces
if len(compbuf):
compbuf += '\n'
compbuf += linestr
co = code.compile_command(compbuf, filename='<HECL>')
if co is not None:
exec(co, globals)
compbuf = str()
except Exception as e:
writepipeline(b'EXCEPTION')
raise

2
hecl/extern/Athena vendored

@ -1 +1 @@
Subproject commit 3d220841c01037af77b5299ea029144e3795242f
Subproject commit f06afb429ccddad1be6878d1b9d6ffebb245909b

@ -1 +1 @@
Subproject commit 73185fc32cfa438b54c9336ed4627135c1011d9d
Subproject commit 8e89d7efd060d756bf756c09c0d285eb944f6610

View File

@ -498,6 +498,19 @@ public:
*/
void getGlobResults(std::vector<SystemString>& outPaths) const;
/**
* @brief Count how many directory levels deep in project path is
* @return Level Count
*/
inline size_t levelCount() const
{
size_t count = 0;
for (SystemChar ch : m_relPath)
if (ch == _S('/') || ch == _S('\\'))
++count;
return count;
}
/**
* @brief Create directory at path
*