Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
8d6cfcb
Revert "Use the numpytoimath library, and Get rid of python2 compat s…
tbttfox Aug 6, 2026
3878b78
Add maya 27 to the workflow
tbttfox Aug 6, 2026
8125994
Fix some Qt6 compatibility
tbttfox Aug 11, 2026
5714b49
Add dialog types loaded from the ui, and some simple type checking er…
tbttfox Aug 11, 2026
2e05af2
First pass typing the alembic stuff. I'm just gonna require numpy next
tbttfox Aug 12, 2026
d840349
Make numpy a reqirement for alembicCommon
tbttfox Aug 12, 2026
d3bd561
Format pysimplex.cpp
tbttfox Sep 4, 2026
7af8a66
Add a couple exposed variables
tbttfox Sep 4, 2026
ceff0a0
Move to a new maya meson paradigm
tbttfox Sep 15, 2026
82a8305
Do the tick accessor and some typing
tbttfox Sep 15, 2026
1f70e7b
Add the simplex hab distro
tbttfox Aug 12, 2026
ebab1e3
Fix alembic typing and the call
tbttfox Aug 12, 2026
cd7c2a8
Fix the drag filter for qt6
tbttfox Aug 12, 2026
0fbad03
Fix a bunch of qt6 stuff, and a double mesh creation on import
tbttfox Aug 12, 2026
53b34a4
Remove qt.py and make sure some of the plugin menu items don't try to…
tbttfox Aug 12, 2026
5d19a2d
Add typing to the drag filter, and point importObjs to the tools repo
tbttfox Aug 13, 2026
226864e
Pull the qt model setup out of the tree
tbttfox Aug 13, 2026
a896fa1
Clear up a bunch of typechecking things. Next is falloffs
tbttfox Aug 13, 2026
c8f7ab4
Split the falloff into a base class and subclasses
tbttfox Aug 13, 2026
6b6a2b1
Expose more stuff
tbttfox Aug 13, 2026
d3cd7f5
Add the new qt model interface
tbttfox Aug 14, 2026
30278de
Re-add the tree item stuff
tbttfox Aug 14, 2026
6139b5d
Make sure all the contextmanagers are run, and clean up the unused pa…
tbttfox Aug 14, 2026
3864e42
Update the class hierarchy to use less Qt by default.
tbttfox Aug 17, 2026
5e2fc2a
I don't need to keep track of the models. The adapter model and obser…
tbttfox Aug 18, 2026
a50b3e9
Make Falloffs and splitting more robust
tbttfox Aug 18, 2026
46a288c
Add future annotation imports, and remove old pylint directives
tbttfox Aug 18, 2026
5064aaf
Clean up a bunch of useless docstrings
tbttfox Aug 18, 2026
31ad976
Numpy is a hard requirement
tbttfox Aug 18, 2026
6865db0
Fix the combo check dialog and a couple order of operation issues
tbttfox Sep 3, 2026
e303d1d
Fix the combo checkstate
tbttfox Sep 3, 2026
c2abb12
Fix splitting and the falloff dialog
tbttfox Sep 3, 2026
0625738
Fix split exports
tbttfox Sep 3, 2026
e641a1e
Fix checkability and header values
tbttfox Sep 3, 2026
a8b7ede
Add some explicit factory methods to the base Falloff to make the req…
tbttfox Sep 3, 2026
1fa5124
Clean up the falloff factory methods
tbttfox Sep 3, 2026
d4284ae
Add a bunch of typehints, and handle newer arrayToNumpy
tbttfox Sep 11, 2026
be7ae78
Switch from old Optional/Union to | and make sure we're getting futur…
tbttfox Sep 11, 2026
abe1abd
Automatically update old format strings to fstrings
tbttfox Sep 11, 2026
827bb36
Fix a bunch of U and F lint warnings
tbttfox Sep 11, 2026
c861734
isort
tbttfox Sep 11, 2026
9bcfe9c
Add a bunch of easy automatic types from pyrefly (hand-checked)
tbttfox Sep 12, 2026
1216d92
Fix the export speed issue
tbttfox Sep 15, 2026
3392373
Add a bunch of alembic stuff, including the walker base class and typ…
tbttfox Sep 16, 2026
d5a8d35
Disable numpy linking by default
tbttfox Sep 16, 2026
52f6fcf
More build
tbttfox Sep 16, 2026
963a098
No macos 13
tbttfox Sep 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
compile_plugin:
strategy:
matrix:
maya: [2022, 2023, 2024, 2025, 2026]
maya: [2022, 2023, 2024, 2025, 2026, 2027]
os: [macos-13, macos-latest, ubuntu-latest, windows-latest]
include:
# Add the maya update versions here
Expand All @@ -26,19 +26,27 @@ jobs:
update: 3
- maya: 2026
update: 2
- maya: 2027
update: 2

# cross-compiling is annoying so just fall back to macos-13
exclude:
- os: macos-latest
maya: 2022
- os: macos-latest
maya: 2023
- os: macos-13
maya: 2022
- os: macos-13
maya: 2023
- os: macos-13
maya: 2024
- os: macos-13
maya: 2025
- os: macos-13
maya: 2026
- os: macos-13
maya: 2027

fail-fast: false

Expand Down
30 changes: 21 additions & 9 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,34 @@ project(

maya_build = get_option('maya_build')
python_build = get_option('python_build')
imath_bridge_build = get_option('imath_bridge_build')

if not maya_build and not python_build
if not maya_build and not python_build and not imath_bridge_build
error('No builds requested')
endif

conf_data = configuration_data()
conf_data.set('VCS_TAG', meson.project_version())

subdir('src/simplexlib')
if maya_build
maya_dep = dependency('maya')
maya_name_suffix = maya_dep.get_variable('name_suffix')
maya_version = maya_dep.get_variable('maya_version')
subdir('src/maya')

if maya_build or imath_bridge_build
subproject('maya')
endif

if imath_bridge_build
subdir('src/imathbridge')
endif

if python_build
subdir('src/python')
if maya_build or python_build
subdir('src/simplexlib')
if maya_build
subdir('src/maya')
endif

if python_build
subdir('src/python')
endif
endif



1 change: 1 addition & 0 deletions meson.options
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
option('maya_build', type : 'boolean', value : true)
option('python_build', type : 'boolean', value : true)
option('imath_bridge_build', type : 'boolean', value : false)
option('python_wheel_build', type : 'boolean', value : false)
option('python_script_build', type : 'boolean', value : false)
6 changes: 3 additions & 3 deletions quick_compile.bat
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
setlocal

SET MAYA_VERSION=2024
SET MAYA_VERSION=2027
REM "vs" "ninja"
REM use VS for the debugger, otherwise use NINJA
REM Until I figure out how to debug using nvim
Expand All @@ -13,8 +13,8 @@ if not exist %BUILDDIR%\ (
meson setup %BUILDDIR% ^
-Dmaya:maya_version=%MAYA_VERSION% ^
-Dmaya_build=true ^
-Dpython_build=false ^
-Dpython_script_build=false ^
-Dpython_build=true ^
-Dpython_script_build=true ^
--buildtype %BUILDTYPE% --vsenv --backend %BACKEND%
)

Expand Down
9 changes: 5 additions & 4 deletions src/maya/meson.build
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
maya_dep = dependency('maya')
maya_name_suffix = maya_dep.get_variable('name_suffix')
maya_version = maya_dep.get_variable('maya_version')
maya_plugin_dep = dependency('maya-plugin')
maya_core_dep = dependency('maya-core')
maya_name_suffix = maya_plugin_dep.get_variable('name_suffix')
maya_version = maya_core_dep.get_variable('maya_version')

simplex_maya_files = files([
'src/basicBlendShape.cpp',
Expand Down Expand Up @@ -29,7 +30,7 @@ simplex_maya = shared_library(
install: true,
install_dir : meson.global_source_root() / 'output_Maya' + maya_version,
include_directories : simplex_maya_inc,
dependencies : [maya_dep, simplexlib_dep],
dependencies : [maya_core_dep, maya_plugin_dep, simplexlib_dep],
name_prefix : '',
name_suffix : maya_name_suffix,
)
131 changes: 49 additions & 82 deletions src/python/pysimplex.cpp
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
#include <Python.h>
#include <structmember.h>

#include "simplex.h"
#include <string>
#include <codecvt>
#include <vector>
#include <locale>
#include <string>
#include <vector>

#include "simplex.h"

typedef struct {
PyObject_HEAD // No Semicolon for this Macro;
PyObject *definition;
simplex::Simplex *sPointer;
PyObject_HEAD // No Semicolon for this Macro;
PyObject* definition;
simplex::Simplex* sPointer;
} PySimplex;

static void
PySimplex_dealloc(PySimplex* self) {
static void PySimplex_dealloc(PySimplex* self) {
Py_XDECREF(self->definition);
if (self->sPointer != NULL)
delete self->sPointer;
if (self->sPointer != NULL) {
delete self->sPointer;
}
PyObject_Del(self);
}

static PyObject *
PySimplex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {

PySimplex *self = PyObject_New(PySimplex, type);
static PyObject* PySimplex_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
PySimplex* self = PyObject_New(PySimplex, type);
if (self != NULL) {
self->definition = PyUnicode_FromString("");
if (self->definition == NULL) {
Expand All @@ -34,27 +33,25 @@ PySimplex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
self->sPointer = new simplex::Simplex();
}

return (PyObject *)self;
return (PyObject*)self;
}

static PyObject *
PySimplex_getdefinition(PySimplex* self, void* closure){
static PyObject* PySimplex_getdefinition(PySimplex* self, void* closure) {
Py_INCREF(self->definition);
return self->definition;
}

static int
PySimplex_setdefinition(PySimplex* self, PyObject* jsValue, void* closure){
if (jsValue == NULL || jsValue == Py_None){
static int PySimplex_setdefinition(PySimplex* self, PyObject* jsValue, void* closure) {
if (jsValue == NULL || jsValue == Py_None) {
jsValue = PyUnicode_FromString("");
}

if (! PyUnicode_Check(jsValue)) {
if (!PyUnicode_Check(jsValue)) {
PyErr_SetString(PyExc_TypeError, "The simplex definition must be a string");
return -1;
}

PyObject *tmp = self->definition;
PyObject* tmp = self->definition;
Py_INCREF(jsValue);
self->definition = jsValue;
Py_DECREF(tmp);
Expand All @@ -72,18 +69,16 @@ PySimplex_setdefinition(PySimplex* self, PyObject* jsValue, void* closure){
return 0;
}

static PyObject *
PySimplex_getexactsolve(PySimplex* self, void* closure){
if (self->sPointer->getExactSolve()){
static PyObject* PySimplex_getexactsolve(PySimplex* self, void* closure) {
if (self->sPointer->getExactSolve()) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
}

static int
PySimplex_setexactsolve(PySimplex* self, PyObject* exact, void* closure){
static int PySimplex_setexactsolve(PySimplex* self, PyObject* exact, void* closure) {
int truthy = PyObject_IsTrue(exact);
if (truthy == -1){
if (truthy == -1) {
PyErr_SetString(PyExc_TypeError, "The value passed cannot be cast to boolean");
return -1;
}
Expand All @@ -92,77 +87,69 @@ PySimplex_setexactsolve(PySimplex* self, PyObject* exact, void* closure){
return 0;
}

static int
PySimplex_init(PySimplex *self, PyObject *args, PyObject *kwds) {
PyObject *jsValue=NULL, *tmp=NULL;
static int PySimplex_init(PySimplex* self, PyObject* args, PyObject* kwds) {
PyObject *jsValue = NULL, *tmp = NULL;

char jsValueLiteral[] = "jsValue";
static char *kwlist[] = {jsValueLiteral, NULL};
static char* kwlist[] = {jsValueLiteral, NULL};

if (! PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &jsValue))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &jsValue)) {
return -1;
}

return PySimplex_setdefinition(self, jsValue, NULL);
}

static PyObject *
PySimplex_solve(PySimplex* self, PyObject* vec){
if (! PySequence_Check(vec)){
static PyObject* PySimplex_solve(PySimplex* self, PyObject* vec) {
if (!PySequence_Check(vec)) {
PyErr_SetString(PyExc_TypeError, "Input must be a list or tuple");
return NULL;
}

PyObject *item;
PyObject* item;
std::vector<double> stdVec, outVec;
for (Py_ssize_t i=0; i<PySequence_Size(vec); ++i){
for (Py_ssize_t i = 0; i < PySequence_Size(vec); ++i) {
item = PySequence_GetItem(vec, i);
if (! PyNumber_Check(item)) {
if (!PyNumber_Check(item)) {
PyErr_SetString(PyExc_TypeError, "Input list can contain only numbers");
return NULL;
}
stdVec.push_back(PyFloat_AsDouble(PyNumber_Float(item)));
Py_DECREF(item);
}

self->sPointer->clearValues();
self->sPointer->clearValues();
outVec = self->sPointer->solve(stdVec);

PyObject *out = PyList_New(outVec.size());
for (size_t i=0; i<outVec.size(); ++i){
PyObject* out = PyList_New(outVec.size());
for (size_t i = 0; i < outVec.size(); ++i) {
PyList_SetItem(out, i, PyFloat_FromDouble(outVec[i]));
}
return out;
}

static PyGetSetDef PySimplex_getseters[] = {
{(char*)"definition",
(getter)PySimplex_getdefinition, (setter)PySimplex_setdefinition,
(char*)"Simplex structure definition string",
NULL},

{(char*)"exactSolve",
(getter)PySimplex_getexactsolve, (setter)PySimplex_setexactsolve,
(char*)"Run the solve with the exact min() solver",
NULL},
{(char*)"definition", (getter)PySimplex_getdefinition, (setter)PySimplex_setdefinition,
(char*)"Simplex structure definition string", NULL},

{(char*)"exactSolve", (getter)PySimplex_getexactsolve, (setter)PySimplex_setexactsolve,
(char*)"Run the solve with the exact min() solver", NULL},
{NULL} // Sentinel
};

static PyMethodDef PySimplex_methods[] = {
{(char*)"solve", (PyCFunction)PySimplex_solve, METH_O,
(char*)"Supply an input list to the solver, and recieve and output list"
},
(char*)"Supply an input list to the solver, and recieve and output list"},
{NULL} // Sentinel
};



static PyType_Slot PySimplexType_Slots[] = {
{Py_tp_methods, PySimplex_methods},
{Py_tp_getset, PySimplex_getseters},
{Py_tp_init, (void*)PySimplex_init},
{Py_tp_new, (void*)PySimplex_new},
{Py_tp_methods, PySimplex_methods},
{ Py_tp_getset, PySimplex_getseters},
{ Py_tp_init, (void*)PySimplex_init},
{ Py_tp_new, (void*)PySimplex_new},
{Py_tp_dealloc, (void*)PySimplex_dealloc},
{0, 0}, // Sentinel
{ 0, 0}, // Sentinel
};

static PyType_Spec PySimplexType_Spec = {
Expand All @@ -172,8 +159,6 @@ static PyType_Spec PySimplexType_Spec = {
.slots = PySimplexType_Slots,
};



static int PySimplexModule_exec(PyObject* module) {
PyObject* pysimplex_type;

Expand All @@ -193,13 +178,11 @@ static int PySimplexModule_exec(PyObject* module) {
return 0;
}


static PyModuleDef_Slot PySimplexModule_Slots[] = {
{Py_mod_exec, (void*)PySimplexModule_exec},
{0, NULL},
{ 0, NULL},
};


static PyModuleDef PySimplexModuleDef = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "pysimplex",
Expand All @@ -209,20 +192,4 @@ static PyModuleDef PySimplexModuleDef = {
.m_slots = PySimplexModule_Slots,
};


PyMODINIT_FUNC PyInit_pysimplex(void) {

return PyModuleDef_Init(&PySimplexModuleDef);
}












PyMODINIT_FUNC PyInit_pysimplex(void) { return PyModuleDef_Init(&PySimplexModuleDef); }
Loading
Loading