Skip to content

Commit

Permalink
Cleaned up get backend logic
Browse files Browse the repository at this point in the history
  • Loading branch information
munkybutt committed Mar 15, 2022
1 parent 8e037d8 commit 23d41bb
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 161 deletions.
51 changes: 30 additions & 21 deletions PYProjects/skin_plus_plus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,35 @@

import importlib
import pathlib
import site
import sys

get_skin_data = None
set_skin_weights = None
# get_vertex_positions = None

def __get_dcc_backend(dcc:str, version: str, api:str):
current_directory = pathlib.Path(__file__).parent
sub_module_name = f"skin_plus_plus_{api}_{version}"
sub_module_path = current_directory / f"dccs/{dcc}" / sub_module_name

print(f"sub_module_path: {sub_module_path}")

if not sub_module_path.exists():
raise FileNotFoundError(f"Unsupported DCC version!")

import_path = f"{__name__}.dccs.{dcc}.{sub_module_name}.skin_plus_plus_{api}"
backend = importlib.import_module(import_path)

global get_skin_data
global set_skin_weights
# global get_vertex_positions

get_skin_data = backend.get_skin_data
set_skin_weights = backend.set_skin_weights
# get_vertex_positions = skin_plus_plus_pymxs.get_vertex_positions

return backend

# DO NOT REMOVE - Required for access to SkinData class:
from . import skin_plus_plus_py

executable = sys.executable.lower()
if "3ds max" in executable:
Expand All @@ -16,29 +39,15 @@

version_info = mxRt.MaxVersion()
version_number = version_info[0]
current_directory = pathlib.Path(__file__).parent
max_sub_module_name = f"skin_plus_plus_pymxs_{version_number}"
max_sub_module_path = current_directory / "dccs/max" / max_sub_module_name

if not max_sub_module_path.exists():
raise FileNotFoundError(f"Unsupported DCC version!")

import_path = f"{__name__}.dccs.max.{max_sub_module_name}.skin_plus_plus_pymxs"
skin_plus_plus_pymxs = importlib.import_module(import_path)

get_skin_data = skin_plus_plus_pymxs.get_skin_data
# get_vertex_positions = skin_plus_plus_pymxs.get_vertex_positions
set_skin_weights = skin_plus_plus_pymxs.set_skin_weights
__get_dcc_backend("max", version_number, "pymxs")


elif "maya" in executable:

# from maya import cmds
from .dccs.maya.skin_plus_plus_pymaya_2022 import skin_plus_plus_pymaya
from pymel import versions

get_skin_data = skin_plus_plus_pymaya.get_skin_data
# get_vertex_positions = skin_plus_plus_pymaya.get_vertex_positions
set_skin_weights = skin_plus_plus_pymaya.set_skin_weights
version = str(versions.current())[:4]
__get_dcc_backend("maya", version, "pymaya")

else:
raise RuntimeError(f"Unsupported executable: {executable}")
Expand Down
Binary file not shown.
Binary file not shown.
Binary file modified PYProjects/skin_plus_plus/skin_plus_plus_py.pyd
Binary file not shown.
25 changes: 0 additions & 25 deletions PYProjects/skin_plus_plus_test/__init__.py
Original file line number Diff line number Diff line change
@@ -1,25 +0,0 @@
import sys

# Required for access to SkinData class:
from . import _skin_plus_plus_py

executable = sys.executable
if "3ds max" in executable:
from ._skin_plus_plus_pymxs import get_data
from ._skin_plus_plus_pymxs import get_vertex_positions
from ._skin_plus_plus_pymxs import set_skin_weights

else:
raise RuntimeError(f"Unsupported executable: {executable}")


from .core import export_skin_data
from .core import import_skin_data

__all__ = (
"export_skin_data",
"get_vertex_positions",
"get_data",
"import_skin_data",
"set_skin_weights"
)
6 changes: 3 additions & 3 deletions PYProjects/skin_plus_plus_test/skin_plus_plus_test.ms
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ pyTime = python.import "time"


_SKINPPOPS = SkinPPOps()
-- -- getPropNames _SKINPPOPS
vals = _SKINPPOPS.GetSkinWeights $Sphere002
vals[3].Count
-- getPropNames _SKINPPOPS
-- vals = _SKINPPOPS.GetSkinWeights $Sphere002
-- vals[3].Count
-- _SKINPPOPS.getPositions $Sphere001

-- SkinPP.GetSkinWeights $Sphere001
Expand Down
30 changes: 16 additions & 14 deletions PYProjects/skin_plus_plus_test/skin_plus_plus_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,32 +370,33 @@ def setup_maya_environment(cls):
def test_get_performance(self):
get_timer_dict: dict[str, tuple[float, Any, str]] = {}

def findRelatedSkinCluster(geometry):
def find_related_skin_cluster(geometry):
if not self.cmds.objExists(geometry):
raise Exception('Object '+geometry+' does not exist!')
raise Exception(f"Object {geometry} does not exist!")

if self.cmds.objectType(geometry) == "transform":
try: geometry = self.cmds.listRelatives(geometry, s=True, ni=True, pa=True)[0]
except: raise Exception('Object '+geometry+' has no deformable geometry!')
except: raise Exception(f"Object {geometry} has no deformable geometry!")

skin = self.mel.eval(f'findRelatedSkinCluster "{geometry}"')
skin = self.mel.eval(f"findRelatedSkinCluster '{geometry}'")
if not skin:
skin = self.cmds.ls(self.cmds.listHistory(geometry),type='skinCluster')
if skin: skin = skin[0]
if not skin: skin = ''
skin = skin[0] if skin else None

if not skin:
raise RuntimeError(f"{geometry} has no skin cluster!")

return skin

@timer(get_timer_dict)
def get_skin_weights_cmds(_obj: str):
def cmds_get_skin_weights(_obj: str):
vertex_count = self.cmds.polyEvaluate(_obj, vertex=True)
skin_cluster = findRelatedSkinCluster(_obj)
skin_cluster = find_related_skin_cluster(_obj)
skin_weights = np.empty((vertex_count, 6), dtype=float)
skin_bone_names = [None] * vertex_count
positions: np.ndarray[float, Any] = np.empty((vertex_count, 3), dtype=float)
for vertex_index in range(vertex_count):
vertex_index_str = f"{_obj}.vtx[{vertex_index}]"

vertex_weights = np.array(
self.cmds.skinPercent(
skin_cluster,
Expand Down Expand Up @@ -428,7 +429,7 @@ def get_skin_weights_cmds(_obj: str):
return skin_weights, positions, skin_bone_names

@timer(get_timer_dict)
def get_skin_weights_pymel(_obj: str):
def pymel_get_skin_weights(_obj: str):

def get_skin_cluster(__obj):
"""Get the skincluster of a given object
Expand Down Expand Up @@ -550,8 +551,8 @@ def skin_plus_plus_get_skin_data(_obj: str):


get_function_list = (
get_skin_weights_cmds,
get_skin_weights_pymel,
cmds_get_skin_weights,
pymel_get_skin_weights,
skin_plus_plus_get_skin_data,
)

Expand Down Expand Up @@ -610,15 +611,16 @@ def set_skin_weights(_obj, _boneIDs, _weights):

if __name__ == "__main__":

# get_skin_weights_cmds("test_mesh_low")
# cmds_get_skin_weights("test_mesh_low")

# from pymxs import runtime as mxRt

# sel = tuple(mxRt.Selection)
# unittest.main()

suite = unittest.TestSuite()
suite.addTest(SkinPlusPlusTestMaya("test_get_performance"))
suite.addTest(SkinPlusPlusTestMax("test_get_performance"))
# suite.addTest(SkinPlusPlusTestMaya("test_get_performance"))
runner = unittest.TextTestRunner()
runner.run(suite)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#define FMT_HEADER_ONLY
#include <fmt/format.h>
#include <fmt/xchar.h>


namespace py = pybind11;
Expand Down
28 changes: 3 additions & 25 deletions PYProjects/source/skin_plus_plus_pymaya/skin_plus_plus_pymaya.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#include <skin_plus_plus_pymaya.h>




//bool getMeshPositions(const MDagPath& dagPath, Array<Vector3>* pointArray)
//{
// nvDebugCheck(pointArray != NULL);
Expand Down Expand Up @@ -108,25 +106,6 @@ PySkinData SkinManagerMaya::getData()

bool SkinManagerMaya::setSkinWeights(eg::MatrixXi& boneIDs, eg::MatrixXf& vertexWeights)
{
/*
if you want to set the weights for three components for influences 7 and 10,
the influence array would contain[7, 10], and the values array would contain:
[
component#1 weight for influence 7,
component #1 weight for influence 10,
component#2 weight for influence 7,
component#2 weight for influence 10,
...
]
setWeights(const MDagPath & path,
const MObject & components,
MIntArray & influenceIndices,
MDoubleArray & values,
bool normalize = true,
MDoubleArray * oldValues = NULL
)
*/

size_t vertexCount = boneIDs.rows();
size_t vertexWeightsRows = vertexWeights.rows();
size_t influenceCount = boneIDs.cols();
Expand All @@ -140,6 +119,7 @@ bool SkinManagerMaya::setSkinWeights(eg::MatrixXi& boneIDs, eg::MatrixXf& vertex
}
if (influenceCount != vertexWeightsCols)
{
//fmt::to_char();
const char* exceptionText = convertStringToChar(
fmt::format("boneIDs column size: {} does not match vertexWeights column size: {}", influenceCount, vertexWeightsCols)
);
Expand All @@ -158,10 +138,6 @@ bool SkinManagerMaya::setSkinWeights(eg::MatrixXi& boneIDs, eg::MatrixXf& vertex
arrayIndex += influenceIndex;
auto boneID = boneIDs(vertexIndex, influenceIndex);
auto vertexWeight = vertexWeights(vertexIndex, influenceIndex);
//if (!fixedIds)
//{
// mBoneIDs[arrayIndex] = boneID;
//}
mWeights[arrayIndex] = vertexWeight;
}
}
Expand All @@ -181,6 +157,8 @@ bool SkinManagerMaya::setSkinWeights(eg::MatrixXi& boneIDs, eg::MatrixXf& vertex


PYBIND11_MODULE(skin_plus_plus_pymaya, m) {
#include <skin_plus_plus_py.h>

m.def("get_skin_data", [&](wchar_t* name)
{
SkinManagerMaya skinData(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ char convertWCharToChar(const wchar_t* text)
return StoreTextBuffer[0];
}

std::string convertWChartoString(const wchar_t* text)
{
std::wstring ws(text);
return std::string(ws.begin(), ws.end());
}

//std::string convertWChartoString(const wchar_t* text)
//{
// //fmt::format(text);
// auto text_ = fmt::to_string(text);
// std::wstring ws(text);
// return std::string(ws.begin(), ws.end());
//}


INode* getChildByName(const wchar_t* name, INode* parent)
{
Expand Down Expand Up @@ -131,36 +135,6 @@ bool SkinManager::initialise(const wchar_t* name)
}


//std::vector<std::vector<std::vector <float>>> SkinManager::getSkinWeights()
//{
// if (!this->isValid)
// {
// throw std::exception("SkinData object is invalid. Cannot get skin weights.");
// }
// unsigned int vertexCount = this->iSkinContextData->GetNumPoints();
// std::vector<std::vector<std::vector <float>>> skinDataArray(
// 2, std::vector<std::vector<float>>(vertexCount)
// );
// for (unsigned int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++)
// {
// auto influenceCount = this->iSkinContextData->GetNumAssignedBones(vertexIndex);
// std::vector<float> influenceWeights(influenceCount);
// std::vector<float> influenceBoneIDs(influenceCount);
// skinDataArray[0][vertexIndex] = influenceWeights; //influenceWeights
// skinDataArray[1][vertexIndex] = influenceBoneIDs; //influenceBoneIDs
// for (auto influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++)
// {
// auto infuenceWeight = this->iSkinContextData->GetBoneWeight(vertexIndex, influenceIndex);
// if (infuenceWeight <= 0.0f) continue;
// auto influenceBoneID = this->iSkinContextData->GetAssignedBone(vertexIndex, influenceIndex);
// influenceWeights[influenceIndex] = infuenceWeight;
// influenceBoneIDs[influenceIndex] = float(influenceBoneID);
// }
// };
// return skinDataArray;
//}
//

void SkinManager::collectWeightsAndBoneIDs(PySkinData* pySkinData, unsigned int vertexIndex)
{
auto influenceCount = this->iSkinContextData->GetNumAssignedBones(vertexIndex);
Expand Down Expand Up @@ -194,7 +168,7 @@ PySkinData* SkinManager::getData()
this->pySkinData->boneNames = std::vector<std::string>(skinBonesCount);
for (auto boneIndex = 0; boneIndex < skinBonesCount; boneIndex++)
{
this->pySkinData->boneNames[boneIndex] = convertWChartoString(this->iSkin->GetBone(boneIndex)->GetName());
this->pySkinData->boneNames[boneIndex] = fmt::to_string(this->iSkin->GetBone(boneIndex)->GetName());
}
auto meshType = getMeshType(this->node);
if (meshType == 0)
Expand Down Expand Up @@ -300,7 +274,7 @@ bool SkinManager::setSkinWeights(PySkinData& skinData)
continue;
}
skinBones.Append(1, &bone);
skinBoneNames[boneIndex] = convertWChartoString(bone->GetName());
skinBoneNames[boneIndex] = fmt::to_string(bone->GetName());
}
auto sortedBoneIDs = getSortedBoneIDs(skinData.boneNames, skinBoneNames);
for (auto vertexIndex = 0; vertexIndex < boneIDsRows; vertexIndex++)
Expand Down Expand Up @@ -330,13 +304,6 @@ bool SkinManager::setSkinWeights(PySkinData& skinData)
}


//inline std::vector<std::vector<std::vector <float>>> getSkinWeights(wchar_t* name)
//{
// SkinManager skinData(name);
// return skinData.getSkinWeights();
//}


bool setSkinWeights(wchar_t* name, PySkinData& skinData)
{
SkinManager skinData_(name);
Expand All @@ -345,35 +312,8 @@ bool setSkinWeights(wchar_t* name, PySkinData& skinData)


PYBIND11_MODULE(skin_plus_plus_pymxs, m) {
//m.def("get_skin_weights", [&](wchar_t* name, int return_type)
// {
// std::vector<std::vector<std::vector<float>>> weights = getSkinWeights(name);
// switch (return_type) {
// case 0:
// return py::cast(weights);
// case 1:
// return py::cast(weights, py::return_value_policy::take_ownership);
// case 2:
// return py::cast(weights, py::return_value_policy::copy);
// case 3:
// return py::cast(weights, py::return_value_policy::move);
// case 4:
// return py::cast(weights, py::return_value_policy::reference);
// case 5:
// return py::cast(weights, py::return_value_policy::reference_internal);
// case 6:
// return py::cast(weights, py::return_value_policy::automatic);
// case 7:
// return py::cast(weights, py::return_value_policy::automatic_reference);
// default:
// return py::cast(weights);
// }
//
// },
// "Get Skin Weights",
// py::arg("name"),
// py::arg("return_type")
//);
#include <skin_plus_plus_py.h>

m.def("get_skin_data", [&](wchar_t* name)
{
SkinManager skinData(name);
Expand Down

0 comments on commit 23d41bb

Please sign in to comment.