From e0f29704fa8f52840684405136a971ccafb65830 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Wed, 17 Jan 2024 12:45:34 +0800 Subject: [PATCH 1/5] PythonFilterPrimsByUserdata --- projects/Alembic/CMakeLists.txt | 7 ++++ projects/Alembic/ReadAlembic.cpp | 63 ++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/projects/Alembic/CMakeLists.txt b/projects/Alembic/CMakeLists.txt index e4252d7510..12a6b50a23 100644 --- a/projects/Alembic/CMakeLists.txt +++ b/projects/Alembic/CMakeLists.txt @@ -32,3 +32,10 @@ endif() find_package(PNG REQUIRED) target_link_libraries(zeno PRIVATE PNG::PNG) + +if (ZENO_WITH_PYTHON3) + find_package(Python3 COMPONENTS Development REQUIRED) + target_compile_definitions(zeno PRIVATE -DZENO_WITH_PYTHON3) + target_link_libraries(zeno PRIVATE ${Python3_LIBRARIES}) + target_include_directories(zeno PRIVATE ${Python3_INCLUDE_DIRS}) +endif() diff --git a/projects/Alembic/ReadAlembic.cpp b/projects/Alembic/ReadAlembic.cpp index ef87435694..903ce6467a 100644 --- a/projects/Alembic/ReadAlembic.cpp +++ b/projects/Alembic/ReadAlembic.cpp @@ -20,6 +20,10 @@ #include #include + #include +#ifdef ZENO_WITH_PYTHON3 +#endif + using namespace Alembic::AbcGeom; namespace zeno { @@ -1081,7 +1085,66 @@ ZENDEFNODE(PrimsFilterInUserdata, { {}, {"alembic"}, }); +//#ifdef ZENO_WITH_PYTHON3 +struct PythonFilterPrimsByUserdata: INode { + void apply() override { + Py_Initialize(); + + PyObject* pModule = PyImport_ImportModule("string_length"); + + if (pModule != NULL) { + PyObject* pFunc = PyObject_GetAttrString(pModule, "get_string_length"); + + if (pFunc && PyCallable_Check(pFunc)) { + std::string inputString = "fuck"; + + PyObject* pArgs = PyTuple_Pack(1, Py_BuildValue("s", inputString.c_str())); + + PyObject* pValue = PyObject_CallObject(pFunc, pArgs); + Py_DECREF(pArgs); + + if (pValue != NULL) { + int length = PyLong_AsLong(pValue); + Py_DECREF(pValue); + + std::cout << "String length returned from Python: " << length << std::endl; + } else { + // 处理 Python 函数调用失败的情况 + PyErr_Print(); + } + + // 释放 Python 函数对象 + Py_DECREF(pFunc); + } else { + // 处理获取 Python 函数失败的情况 + PyErr_Print(); + } + + // 释放 Python 模块对象 + Py_DECREF(pModule); + } else { + // 处理导入 Python 模块失败的情况 + PyErr_Print(); + } + + // 结束 Python 解释器 + Py_Finalize(); + } +}; +ZENDEFNODE(PythonFilterPrimsByUserdata, { + { + {"list", "list"}, + {"string", "name", ""}, + {"string", "filters"}, + {"bool", "contain", "1"}, + }, + { + }, + {}, + {"alembic"}, +}); +//#endif } // namespace zeno From d35d915962e3060a62500ce2ab82a1e319fb49e9 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Wed, 17 Jan 2024 16:40:56 +0800 Subject: [PATCH 2/5] PrimsFilterInUserdataPython --- projects/Alembic/ReadAlembic.cpp | 80 ++++++++++++++++---------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/projects/Alembic/ReadAlembic.cpp b/projects/Alembic/ReadAlembic.cpp index 903ce6467a..3fc17ccc49 100644 --- a/projects/Alembic/ReadAlembic.cpp +++ b/projects/Alembic/ReadAlembic.cpp @@ -19,9 +19,10 @@ #include #include #include +#include - #include #ifdef ZENO_WITH_PYTHON3 + #include #endif using namespace Alembic::AbcGeom; @@ -1085,66 +1086,63 @@ ZENDEFNODE(PrimsFilterInUserdata, { {}, {"alembic"}, }); -//#ifdef ZENO_WITH_PYTHON3 -struct PythonFilterPrimsByUserdata: INode { - void apply() override { - Py_Initialize(); - PyObject* pModule = PyImport_ImportModule("string_length"); - - if (pModule != NULL) { - PyObject* pFunc = PyObject_GetAttrString(pModule, "get_string_length"); - - if (pFunc && PyCallable_Check(pFunc)) { - std::string inputString = "fuck"; +static PyObject * pycheck(PyObject *pResult) { + if (pResult == nullptr) { + PyErr_Print(); + throw zeno::makeError("python err"); + } + return pResult; +} +#ifdef ZENO_WITH_PYTHON3 +struct PrimsFilterInUserdataPython: INode { + void apply() override { + auto prims = get_input("list")->get(); - PyObject* pArgs = PyTuple_Pack(1, Py_BuildValue("s", inputString.c_str())); + auto py_code = get_input2("py_code"); + Py_Initialize(); + zeno::scope_exit init_defer([=]{ Py_Finalize(); }); - PyObject* pValue = PyObject_CallObject(pFunc, pArgs); - Py_DECREF(pArgs); + PyObject *globals = PyDict_New(); + zeno::scope_exit globals_defer([=]{ Py_DECREF(globals); }); + auto name = get_input2("name"); + auto out_list = std::make_shared(); + for (auto p: prims) { + auto &ud = p->userData(); + auto value = ud.get2(name); - if (pValue != NULL) { - int length = PyLong_AsLong(pValue); - Py_DECREF(pValue); + PyObject *locals = PyDict_New(); + zeno::scope_exit locals_defer([=]{ Py_DECREF(locals); }); + PyObject* pyValue = PyUnicode_DecodeUTF8(value.c_str(), value.size(), "strict"); + PyDict_SetItemString(locals, "v", pyValue); - std::cout << "String length returned from Python: " << length << std::endl; - } else { - // 处理 Python 函数调用失败的情况 - PyErr_Print(); - } + PyObject *pResult = pycheck(PyRun_String(py_code.c_str(), Py_file_input, globals, locals)); + zeno::scope_exit pResult_defer([=]{ Py_DECREF(pResult); }); + PyObject *pValue = pycheck(PyRun_String("result", Py_eval_input, globals, locals)); + zeno::scope_exit pValue_defer([=]{ Py_DECREF(pValue); }); + long need_insert = PyLong_AsLong(pValue); - // 释放 Python 函数对象 - Py_DECREF(pFunc); - } else { - // 处理获取 Python 函数失败的情况 - PyErr_Print(); + if (need_insert > 0) { + out_list->arr.push_back(p); } - - // 释放 Python 模块对象 - Py_DECREF(pModule); - } else { - // 处理导入 Python 模块失败的情况 - PyErr_Print(); } - - // 结束 Python 解释器 - Py_Finalize(); + set_output("out", out_list); } }; -ZENDEFNODE(PythonFilterPrimsByUserdata, { +ZENDEFNODE(PrimsFilterInUserdataPython, { { {"list", "list"}, {"string", "name", ""}, - {"string", "filters"}, - {"bool", "contain", "1"}, + {"multiline_string", "py_code", "result = v.startswith('hello')"}, }, { + {"out"}, }, {}, {"alembic"}, }); -//#endif +#endif } // namespace zeno From 38bd62b2d94d5477ad6285850ad25f884de2f740 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Wed, 17 Jan 2024 16:42:37 +0800 Subject: [PATCH 3/5] fix --- projects/Alembic/ReadAlembic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/Alembic/ReadAlembic.cpp b/projects/Alembic/ReadAlembic.cpp index 3fc17ccc49..ba13eb57b4 100644 --- a/projects/Alembic/ReadAlembic.cpp +++ b/projects/Alembic/ReadAlembic.cpp @@ -1087,6 +1087,7 @@ ZENDEFNODE(PrimsFilterInUserdata, { {"alembic"}, }); +#ifdef ZENO_WITH_PYTHON3 static PyObject * pycheck(PyObject *pResult) { if (pResult == nullptr) { PyErr_Print(); @@ -1094,7 +1095,6 @@ static PyObject * pycheck(PyObject *pResult) { } return pResult; } -#ifdef ZENO_WITH_PYTHON3 struct PrimsFilterInUserdataPython: INode { void apply() override { auto prims = get_input("list")->get(); From b172fa3d8aad47ea88260d1784b84bcd23f0a1d1 Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Wed, 17 Jan 2024 19:07:03 +0800 Subject: [PATCH 4/5] improve --- projects/Alembic/ReadAlembic.cpp | 50 +++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/projects/Alembic/ReadAlembic.cpp b/projects/Alembic/ReadAlembic.cpp index ba13eb57b4..31bf8b8fa7 100644 --- a/projects/Alembic/ReadAlembic.cpp +++ b/projects/Alembic/ReadAlembic.cpp @@ -1095,32 +1095,55 @@ static PyObject * pycheck(PyObject *pResult) { } return pResult; } + +static void pycheck(int result) { + if (result != 0) { + PyErr_Print(); + throw zeno::makeError("python err"); + } +} struct PrimsFilterInUserdataPython: INode { void apply() override { auto prims = get_input("list")->get(); - auto py_code = get_input2("py_code"); Py_Initialize(); zeno::scope_exit init_defer([=]{ Py_Finalize(); }); - PyObject *globals = PyDict_New(); - zeno::scope_exit globals_defer([=]{ Py_DECREF(globals); }); - auto name = get_input2("name"); auto out_list = std::make_shared(); for (auto p: prims) { + PyObject* userGlobals = PyDict_New(); + zeno::scope_exit userGlobals_defer([=]{ Py_DECREF(userGlobals); }); + + PyObject* innerDict = PyDict_New(); + zeno::scope_exit innerDict_defer([=]{ Py_DECREF(innerDict); }); + auto &ud = p->userData(); - auto value = ud.get2(name); + for (auto i = ud.begin(); i != ud.end(); i++) { + auto key = i->first; + if (ud.has(key)) { + auto value = ud.get2(key); + PyObject* pyInnerValue = PyUnicode_DecodeUTF8(key.c_str(), key.size(), "strict"); + pycheck(PyDict_SetItemString(innerDict, key.c_str(), pyInnerValue)); + } + else if (ud.has(key)) { + auto value = ud.get2(key); + PyObject* pyInnerValue = PyFloat_FromDouble(value); + pycheck(PyDict_SetItemString(innerDict, key.c_str(), pyInnerValue)); + } + else if (ud.has(key)) { + auto value = ud.get2(key); + PyObject* pyInnerValue = PyLong_FromLong(value); + pycheck(PyDict_SetItemString(innerDict, key.c_str(), pyInnerValue)); + } + } - PyObject *locals = PyDict_New(); - zeno::scope_exit locals_defer([=]{ Py_DECREF(locals); }); - PyObject* pyValue = PyUnicode_DecodeUTF8(value.c_str(), value.size(), "strict"); - PyDict_SetItemString(locals, "v", pyValue); + PyDict_SetItemString(userGlobals, "ud", innerDict); - PyObject *pResult = pycheck(PyRun_String(py_code.c_str(), Py_file_input, globals, locals)); + PyObject* pResult = pycheck(PyRun_String(py_code.c_str(), Py_file_input, userGlobals, nullptr)); zeno::scope_exit pResult_defer([=]{ Py_DECREF(pResult); }); - PyObject *pValue = pycheck(PyRun_String("result", Py_eval_input, globals, locals)); + PyObject* pValue = pycheck(PyRun_String("result", Py_eval_input, userGlobals, nullptr)); zeno::scope_exit pValue_defer([=]{ Py_DECREF(pValue); }); - long need_insert = PyLong_AsLong(pValue); + int need_insert = PyLong_AsLong(pValue); if (need_insert > 0) { out_list->arr.push_back(p); @@ -1133,8 +1156,7 @@ struct PrimsFilterInUserdataPython: INode { ZENDEFNODE(PrimsFilterInUserdataPython, { { {"list", "list"}, - {"string", "name", ""}, - {"multiline_string", "py_code", "result = v.startswith('hello')"}, + {"multiline_string", "py_code", "result = len(ud['label']) > 2"}, }, { {"out"}, From b2128b3f434f6f629f5eb4f8d9b5f939bbef27af Mon Sep 17 00:00:00 2001 From: zhouhang95 <765229842@qq.com> Date: Thu, 18 Jan 2024 18:24:45 +0800 Subject: [PATCH 5/5] error callback --- projects/Alembic/ReadAlembic.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/Alembic/ReadAlembic.cpp b/projects/Alembic/ReadAlembic.cpp index 31bf8b8fa7..f8504fd13b 100644 --- a/projects/Alembic/ReadAlembic.cpp +++ b/projects/Alembic/ReadAlembic.cpp @@ -1108,6 +1108,7 @@ struct PrimsFilterInUserdataPython: INode { auto py_code = get_input2("py_code"); Py_Initialize(); zeno::scope_exit init_defer([=]{ Py_Finalize(); }); + PyRun_SimpleString("import sys; sys.stderr = sys.stdout"); auto out_list = std::make_shared(); for (auto p: prims) {