mirror of https://github.com/AxioDL/metaforce.git
blender interface updates
This commit is contained in:
parent
31aa40cc77
commit
807b42d475
|
@ -313,6 +313,13 @@ BlenderConnection::~BlenderConnection()
|
|||
|
||||
bool BlenderConnection::createBlend(const SystemString& path)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_lock, std::try_to_lock);
|
||||
if (!lk)
|
||||
{
|
||||
BlenderLog.report(LogVisor::FatalError,
|
||||
"BlenderConnection::createBlend() musn't be called with stream active");
|
||||
return false;
|
||||
}
|
||||
HECL::SystemUTF8View pathView(path);
|
||||
_writeLine(("CREATE \"" + pathView.str() + "\"").c_str());
|
||||
char lineBuf[256];
|
||||
|
@ -327,6 +334,13 @@ bool BlenderConnection::createBlend(const SystemString& path)
|
|||
|
||||
bool BlenderConnection::openBlend(const SystemString& path)
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_lock, std::try_to_lock);
|
||||
if (!lk)
|
||||
{
|
||||
BlenderLog.report(LogVisor::FatalError,
|
||||
"BlenderConnection::openBlend() musn't be called with stream active");
|
||||
return false;
|
||||
}
|
||||
HECL::SystemUTF8View pathView(path);
|
||||
_writeLine(("OPEN \"" + pathView.str() + "\"").c_str());
|
||||
char lineBuf[256];
|
||||
|
@ -341,6 +355,13 @@ bool BlenderConnection::openBlend(const SystemString& path)
|
|||
|
||||
bool BlenderConnection::saveBlend()
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_lock, std::try_to_lock);
|
||||
if (!lk)
|
||||
{
|
||||
BlenderLog.report(LogVisor::FatalError,
|
||||
"BlenderConnection::saveBlend() musn't be called with stream active");
|
||||
return false;
|
||||
}
|
||||
_writeLine("SAVE");
|
||||
char lineBuf[256];
|
||||
_readLine(lineBuf, sizeof(lineBuf));
|
||||
|
@ -349,12 +370,20 @@ bool BlenderConnection::saveBlend()
|
|||
return false;
|
||||
}
|
||||
|
||||
void BlenderConnection::PyOutStream::linkBlend(const SystemString& relPath, const std::string& objName,
|
||||
void BlenderConnection::deleteBlend()
|
||||
{
|
||||
if (m_loadedBlend.size())
|
||||
{
|
||||
HECL::Unlink(m_loadedBlend.c_str());
|
||||
m_loadedBlend.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void BlenderConnection::PyOutStream::linkBlend(const SystemString& target, 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"
|
||||
" 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"
|
||||
|
@ -368,7 +397,7 @@ void BlenderConnection::PyOutStream::linkBlend(const SystemString& relPath, cons
|
|||
"else:\n"
|
||||
" obj = bpy.data.objects['%s']\n"
|
||||
"\n",
|
||||
objName.c_str(), relView.str().c_str(), link?"True":"False",
|
||||
objName.c_str(), target.c_str(), link?"True":"False",
|
||||
objName.c_str(), objName.c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
bool createBlend(const SystemString& path);
|
||||
bool openBlend(const SystemString& path);
|
||||
bool saveBlend();
|
||||
void deleteBlend();
|
||||
enum CookPlatform
|
||||
{
|
||||
CP_MODERN = 0,
|
||||
|
@ -62,31 +63,43 @@ public:
|
|||
friend class BlenderConnection;
|
||||
std::unique_lock<std::mutex> m_lk;
|
||||
BlenderConnection* m_parent;
|
||||
bool m_deleteOnError;
|
||||
struct StreamBuf : std::streambuf
|
||||
{
|
||||
BlenderConnection* m_parent;
|
||||
PyOutStream& m_parent;
|
||||
std::string m_lineBuf;
|
||||
StreamBuf(BlenderConnection* parent) : m_parent(parent) {}
|
||||
bool m_deleteOnError;
|
||||
StreamBuf(PyOutStream& parent, bool deleteOnError)
|
||||
: m_parent(parent), m_deleteOnError(deleteOnError) {}
|
||||
StreamBuf(const StreamBuf& other) = delete;
|
||||
StreamBuf(StreamBuf&& other) = default;
|
||||
int_type overflow(int_type ch)
|
||||
{
|
||||
if (!m_parent.m_lk)
|
||||
BlenderLog.report(LogVisor::FatalError, "lock not held for PyOutStream writing");
|
||||
if (ch != traits_type::eof() && ch != '\n')
|
||||
{
|
||||
m_lineBuf += char_type(ch);
|
||||
return ch;
|
||||
}
|
||||
m_parent->_writeLine(m_lineBuf.c_str());
|
||||
m_parent.m_parent->_writeLine(m_lineBuf.c_str());
|
||||
char readBuf[16];
|
||||
m_parent->_readLine(readBuf, 16);
|
||||
m_parent.m_parent->_readLine(readBuf, 16);
|
||||
if (strcmp(readBuf, "OK"))
|
||||
{
|
||||
if (m_deleteOnError)
|
||||
m_parent.m_parent->deleteBlend();
|
||||
BlenderLog.report(LogVisor::FatalError, "error sending '%s' to blender", m_lineBuf.c_str());
|
||||
}
|
||||
m_lineBuf.clear();
|
||||
return ch;
|
||||
}
|
||||
} m_sbuf;
|
||||
PyOutStream(BlenderConnection* parent)
|
||||
: m_lk(parent->m_lock), m_parent(parent), m_sbuf(parent), std::ostream(&m_sbuf)
|
||||
PyOutStream(BlenderConnection* parent, bool deleteOnError)
|
||||
: m_lk(parent->m_lock), m_parent(parent),
|
||||
m_sbuf(*this, deleteOnError),
|
||||
m_deleteOnError(deleteOnError),
|
||||
std::ostream(&m_sbuf)
|
||||
{
|
||||
m_parent->_writeLine("PYBEGIN");
|
||||
char readBuf[16];
|
||||
|
@ -99,9 +112,10 @@ public:
|
|||
PyOutStream(PyOutStream&& other)
|
||||
: m_lk(std::move(other.m_lk)), m_parent(other.m_parent), m_sbuf(std::move(other.m_sbuf))
|
||||
{other.m_parent = nullptr;}
|
||||
~PyOutStream()
|
||||
~PyOutStream() {close();}
|
||||
void close()
|
||||
{
|
||||
if (m_parent)
|
||||
if (m_parent && m_lk)
|
||||
{
|
||||
m_parent->_writeLine("PYEND");
|
||||
char readBuf[16];
|
||||
|
@ -109,9 +123,12 @@ public:
|
|||
if (strcmp(readBuf, "DONE"))
|
||||
BlenderLog.report(LogVisor::FatalError, "unable to close PyOutStream with blender");
|
||||
}
|
||||
m_lk.unlock();
|
||||
}
|
||||
void format(const char* fmt, ...)
|
||||
{
|
||||
if (!m_lk)
|
||||
BlenderLog.report(LogVisor::FatalError, "lock not held for PyOutStream::format()");
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
char* result = nullptr;
|
||||
|
@ -123,9 +140,9 @@ public:
|
|||
}
|
||||
void linkBlend(const SystemString& target, const std::string& objName, bool link=true);
|
||||
};
|
||||
inline PyOutStream beginPythonOut()
|
||||
inline PyOutStream beginPythonOut(bool deleteOnError=false)
|
||||
{
|
||||
return PyOutStream(this);
|
||||
return PyOutStream(this, deleteOnError);
|
||||
}
|
||||
|
||||
void quitBlender();
|
||||
|
|
|
@ -15,7 +15,7 @@ class Nodegrid:
|
|||
self.col_roffs = [[0.0,0.0]] * self.ncol
|
||||
for i in range(self.ncol):
|
||||
self.heights.append(0.0)
|
||||
frame_node = new_nodetree.nodes.new('NodeFrame')
|
||||
frame_node = nodetree.nodes.new('NodeFrame')
|
||||
frame_node.label = FRAME_NAMES[i]
|
||||
frame_node.use_custom_color = True
|
||||
frame_node.color = FRAME_COLORS[i]
|
||||
|
|
|
@ -6,14 +6,15 @@ bl_info = {
|
|||
"name": "HECL",
|
||||
"author": "Jack Andersen <jackoalan@gmail.com>",
|
||||
"version": (1, 0),
|
||||
"blender": (2, 69),
|
||||
"blender": (2, 74),
|
||||
"tracker_url": "https://github.com/RetroView/hecl/issues/new",
|
||||
"location": "Properties > Scene > HECL",
|
||||
"description": "Enables blender to gather meshes, materials, and textures for hecl",
|
||||
"category": "System"}
|
||||
|
||||
# Package import
|
||||
from . import hmdl, sact
|
||||
from . import hmdl, sact, Nodegrid
|
||||
Nodegrid = Nodegrid.Nodegrid
|
||||
import bpy, os, sys
|
||||
from bpy.app.handlers import persistent
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import bpy, sys, os, re, code
|
||||
import bpy, sys, os, re
|
||||
|
||||
ARGS_PATTERN = re.compile(r'''(?:"([^"]+)"|'([^']+)'|(\S+))''')
|
||||
|
||||
|
@ -44,6 +44,22 @@ ackbytes = readpipeline()
|
|||
if ackbytes != b'ACK':
|
||||
quitblender()
|
||||
|
||||
# Count brackets
|
||||
def count_brackets(linestr):
|
||||
bracket_count = 0
|
||||
for ch in linestr:
|
||||
if ch in {'[','{','('}:
|
||||
bracket_count += 1
|
||||
elif ch in {']','}',')'}:
|
||||
bracket_count -= 1
|
||||
return bracket_count
|
||||
|
||||
# Complete sequences of statements compiled/executed here
|
||||
def exec_compbuf(compbuf, globals):
|
||||
#print('EXEC', compbuf)
|
||||
co = compile(compbuf, '<HECL>', 'exec')
|
||||
exec(co, globals)
|
||||
|
||||
# Command loop
|
||||
while True:
|
||||
cmdline = readpipeline()
|
||||
|
@ -80,34 +96,46 @@ while True:
|
|||
|
||||
elif cmdargs[0] == 'PYBEGIN':
|
||||
writepipeline(b'READY')
|
||||
globals = dict()
|
||||
globals = {'hecl':hecl}
|
||||
compbuf = str()
|
||||
prev_leading_spaces = 0
|
||||
bracket_count = 0
|
||||
while True:
|
||||
try:
|
||||
line = readpipeline()
|
||||
|
||||
# End check
|
||||
if line == b'PYEND':
|
||||
# Ensure remaining block gets executed
|
||||
if len(compbuf):
|
||||
exec_compbuf(compbuf, globals)
|
||||
compbuf = str()
|
||||
writepipeline(b'DONE')
|
||||
break
|
||||
linestr = line.decode()
|
||||
if linestr.isspace() or not len(linestr):
|
||||
|
||||
# Syntax filter
|
||||
linestr = line.decode().rstrip()
|
||||
if not len(linestr) or linestr.lstrip()[0] == '#':
|
||||
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
|
||||
|
||||
# Block lines always get appended right away
|
||||
if linestr.endswith(':') or leading_spaces or bracket_count:
|
||||
if len(compbuf):
|
||||
compbuf += '\n'
|
||||
compbuf += linestr
|
||||
bracket_count += count_brackets(linestr)
|
||||
writepipeline(b'OK')
|
||||
continue
|
||||
|
||||
# Complete non-block statement in compbuf
|
||||
if len(compbuf):
|
||||
compbuf += '\n'
|
||||
compbuf += linestr
|
||||
co = code.compile_command(compbuf, filename='<HECL>')
|
||||
if co is not None:
|
||||
exec(co, globals)
|
||||
compbuf = str()
|
||||
exec_compbuf(compbuf, globals)
|
||||
|
||||
# Establish new compbuf
|
||||
compbuf = linestr
|
||||
bracket_count += count_brackets(linestr)
|
||||
|
||||
except Exception as e:
|
||||
writepipeline(b'EXCEPTION')
|
||||
raise
|
||||
|
|
|
@ -44,12 +44,13 @@ public:
|
|||
LogModule.report(LogVisor::FatalError, "hecl extract must be ran within a project directory");
|
||||
|
||||
size_t ErrorRef = LogVisor::ErrorCount;
|
||||
HECL::ProjectRootPath newProjRoot(baseFile);
|
||||
HECL::SystemString rootDir = info.cwd + '/' + baseFile;
|
||||
HECL::ProjectRootPath newProjRoot(rootDir);
|
||||
newProjRoot.makeDir();
|
||||
m_fallbackProj.reset(new HECL::Database::Project(newProjRoot));
|
||||
if (LogVisor::ErrorCount > ErrorRef)
|
||||
LogModule.report(LogVisor::FatalError, "unable to init project at '%s'", baseFile.c_str());
|
||||
LogModule.report(LogVisor::Info, _S("initialized project at '%s/.hecl'"), baseFile.c_str());
|
||||
LogModule.report(LogVisor::FatalError, "unable to init project at '%s'", rootDir.c_str());
|
||||
LogModule.report(LogVisor::Info, _S("initialized project at '%s/.hecl'"), rootDir.c_str());
|
||||
m_useProj = m_fallbackProj.get();
|
||||
}
|
||||
else
|
||||
|
@ -68,7 +69,7 @@ public:
|
|||
HECL::Database::IDataSpec* ds = entry->m_factory(*m_useProj, HECL::Database::TOOL_EXTRACT);
|
||||
if (ds)
|
||||
{
|
||||
if (ds->canExtract(*m_useProj, m_einfo, m_reps))
|
||||
if (ds->canExtract(m_einfo, m_reps))
|
||||
m_specPasses.emplace_back(entry, ds);
|
||||
else
|
||||
delete ds;
|
||||
|
@ -184,7 +185,7 @@ public:
|
|||
#endif
|
||||
|
||||
int lineIdx = 0;
|
||||
ds.m_instance->doExtract(*m_useProj, m_einfo,
|
||||
ds.m_instance->doExtract(m_einfo,
|
||||
[&lineIdx](const HECL::SystemChar* message, int lidx, float factor)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit f06afb429ccddad1be6878d1b9d6ffebb245909b
|
||||
Subproject commit 9ed090b12629ddb8a431b871340276da61e88442
|
|
@ -1 +1 @@
|
|||
Subproject commit 8e89d7efd060d756bf756c09c0d285eb944f6610
|
||||
Subproject commit aeb6089053a46c51b55727e68406bb7577c2e60e
|
|
@ -217,9 +217,9 @@ public:
|
|||
|
||||
typedef std::function<void(const HECL::SystemChar*, int, float)> FExtractProgress;
|
||||
|
||||
virtual bool canExtract(Project&, const ExtractPassInfo& info, std::vector<ExtractReport>& reps)
|
||||
virtual bool canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps)
|
||||
{(void)info;LogModule.report(LogVisor::Error, "not implemented");return false;}
|
||||
virtual void doExtract(Project&, const ExtractPassInfo& info, FExtractProgress progress)
|
||||
virtual void doExtract(const ExtractPassInfo& info, FExtractProgress progress)
|
||||
{(void)info;(void)progress;}
|
||||
|
||||
/**
|
||||
|
@ -233,10 +233,10 @@ public:
|
|||
ProjectPath path;
|
||||
ProjectPath cookedPath;
|
||||
};
|
||||
virtual bool canCook(const Project&, const CookTaskInfo& info,
|
||||
virtual bool canCook(const CookTaskInfo& info,
|
||||
SystemString& reasonNo)
|
||||
{(void)info;reasonNo=_S("not implemented");return false;}
|
||||
virtual void doCook(const Project&, const CookTaskInfo& info)
|
||||
virtual void doCook(const CookTaskInfo& info)
|
||||
{(void)info;}
|
||||
|
||||
/**
|
||||
|
@ -252,13 +252,13 @@ public:
|
|||
ProjectPath subpath;
|
||||
ProjectPath outpath;
|
||||
};
|
||||
virtual bool canPackage(const Project&, const PackagePassInfo& info,
|
||||
virtual bool canPackage(const PackagePassInfo& info,
|
||||
SystemString& reasonNo)
|
||||
{(void)info;reasonNo=_S("not implemented");return false;}
|
||||
virtual void gatherDependencies(const Project&, const PackagePassInfo& info,
|
||||
virtual void gatherDependencies(const PackagePassInfo& info,
|
||||
std::unordered_set<ProjectPath>& implicitsOut)
|
||||
{(void)info;(void)implicitsOut;}
|
||||
virtual void doPackage(const Project&, const PackagePassInfo& info)
|
||||
virtual void doPackage(const PackagePassInfo& info)
|
||||
{(void)info;}
|
||||
};
|
||||
|
||||
|
|
|
@ -122,6 +122,15 @@ inline std::string operator+(const char* lhs, const SystemStringView& rhs) {retu
|
|||
typedef struct stat Sstat;
|
||||
#endif
|
||||
|
||||
static inline void Unlink(const SystemChar* file)
|
||||
{
|
||||
#if _WIN32
|
||||
_wunlink(file);
|
||||
#else
|
||||
unlink(file);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void MakeDir(const SystemChar* dir)
|
||||
{
|
||||
#if _WIN32
|
||||
|
|
Loading…
Reference in New Issue