diff --git a/PYProjects/.projects/SkinPlusPlus.sublime-project b/PYProjects/.projects/SkinPlusPlus.sublime-project
index 2895164..3964320 100644
--- a/PYProjects/.projects/SkinPlusPlus.sublime-project
+++ b/PYProjects/.projects/SkinPlusPlus.sublime-project
@@ -2,7 +2,13 @@
"folders":
[
{
- "path": "../../../SkinPlusPlus",
- }
+ "path": "C:\\p4ws\\sharkmob\\Tools\\tech_art\\base\\_standalone\\c++\\SkinPlusPlus",
+ },
+ {
+ "path": "C:\\p4ws\\sharkmob\\Tools\\tech_art\\base\\_standalone\\python\\_third_party"
+ },
+ ],
+ "debugger_configurations":
+ [
],
}
diff --git a/PYProjects/skin_plus_plus/.vscode/launch.json b/PYProjects/skin_plus_plus/.vscode/launch.json
new file mode 100644
index 0000000..ad3d7cb
--- /dev/null
+++ b/PYProjects/skin_plus_plus/.vscode/launch.json
@@ -0,0 +1,18 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "3DsMax",
+ "type": "python",
+ "request": "attach",
+ "connect": {
+ "host": "localhost",
+ "port": 6000
+ },
+ "justMyCode": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/PYProjects/skin_plus_plus/__init__.py b/PYProjects/skin_plus_plus/__init__.py
index 7f8b906..01aded5 100644
--- a/PYProjects/skin_plus_plus/__init__.py
+++ b/PYProjects/skin_plus_plus/__init__.py
@@ -10,13 +10,21 @@
get_skin_data = None
set_skin_weights = None
skin_plus_plus_py = None
+SkinData = None
# get_vertex_positions = None
+try:
+ is_reloading # type: ignore
+ is_reloading = True
+except NameError:
+ is_reloading = False
+
__py_version__ = f"{sys.version_info.major}{sys.version_info.minor}"
def __get_skin_plus_plus_py(python_version: str, debug: bool = False):
global skin_plus_plus_py
+ global SkinData
debug = bool(os.environ.get("SKIN_PLUS_PLUS_DEBUG", False)) or debug
if debug:
@@ -34,6 +42,11 @@ def __get_skin_plus_plus_py(python_version: str, debug: bool = False):
del sys.modules["skin_plus_plus_py"]
skin_plus_plus_py = importlib.import_module(import_path)
+ if is_reloading:
+ importlib.reload(skin_plus_plus_py)
+
+ SkinData = skin_plus_plus_py.SkinData
+
return skin_plus_plus_py
@@ -47,6 +60,8 @@ def __get_dcc_backend(dcc:str, version: str, api:str):
import_path = f"{__name__}.dccs.{dcc}.{sub_module_name}.skin_plus_plus_{api}"
backend = importlib.import_module(import_path)
+ if is_reloading:
+ importlib.reload(backend)
global get_skin_data
global set_skin_weights
@@ -171,3 +186,6 @@ def __getattr__(name: str) -> Any:
"max_to_maya",
"maya_to_max"
)
+
+def __dir__():
+ return __all__
diff --git a/PYProjects/skin_plus_plus/__init__.pyi b/PYProjects/skin_plus_plus/__init__.pyi
index fc54ebf..c4eefbe 100644
--- a/PYProjects/skin_plus_plus/__init__.pyi
+++ b/PYProjects/skin_plus_plus/__init__.pyi
@@ -1,5 +1,6 @@
import numpy as np
import numpy.typing as np_typing
+import typing
from .core import FileType as _FileType
from .core import export_skin_data as _export_skin_data
@@ -45,11 +46,30 @@ class SkinData:
- `weights`: The weights of each influence assigned to each vertext.
- `positions`: The positions of each vertex.
"""
+
bone_names: list[str]
bone_ids: np_typing.NDArray[np.int64]
weights: np_typing.NDArray[np.float32]
positions: np_typing.NDArray[np.float32]
+ @typing.overload
+ def __init__(self):
+ ...
+
+ @typing.overload
+ def __init__(
+ self,
+ names: tuple[str, ...],
+ bone_ids: tuple[tuple[int, ...], ...],
+ weights: tuple[tuple[float, ...], ...],
+ positions: tuple[tuple[float, float, float], ...],
+ ):
+ ...
+
+
+def get_skin_data(mesh_name: str) -> SkinData:
+ ...
+
-def get_skin_data(mesh_name: str) -> SkinData: ...
-def set_skin_weights(mesh_name: str, skin_data: SkinData) -> bool: ...
+def set_skin_weights(mesh_name: str, skin_data: SkinData) -> bool:
+ ...
diff --git a/PYProjects/skin_plus_plus/core.py b/PYProjects/skin_plus_plus/core.py
index bd156a8..75502ab 100644
--- a/PYProjects/skin_plus_plus/core.py
+++ b/PYProjects/skin_plus_plus/core.py
@@ -115,6 +115,8 @@ def import_skin_data(
tuple(data["positions"])
)
+ print(f"skin_data.bone_ids: {skin_data.bone_ids}")
+
return set_skin_weights(mesh_name, skin_data)
# if import_type == ImportType.nearest:
diff --git a/PYProjects/skin_plus_plus/dccs/max/skin_plus_plus_pymxs_2023/skin_plus_plus_pymxs.exp b/PYProjects/skin_plus_plus/dccs/max/skin_plus_plus_pymxs_2023/skin_plus_plus_pymxs.exp
index 0b7af57..3a22b0f 100644
Binary files a/PYProjects/skin_plus_plus/dccs/max/skin_plus_plus_pymxs_2023/skin_plus_plus_pymxs.exp and b/PYProjects/skin_plus_plus/dccs/max/skin_plus_plus_pymxs_2023/skin_plus_plus_pymxs.exp differ
diff --git a/PYProjects/skin_plus_plus/dccs/max/skin_plus_plus_pymxs_2023/skin_plus_plus_pymxs.pyd b/PYProjects/skin_plus_plus/dccs/max/skin_plus_plus_pymxs_2023/skin_plus_plus_pymxs.pyd
index 84a2ac3..52de632 100644
Binary files a/PYProjects/skin_plus_plus/dccs/max/skin_plus_plus_pymxs_2023/skin_plus_plus_pymxs.pyd and b/PYProjects/skin_plus_plus/dccs/max/skin_plus_plus_pymxs_2023/skin_plus_plus_pymxs.pyd differ
diff --git a/PYProjects/skin_plus_plus/dccs/maya/skin_plus_plus_pymaya_2023/skin_plus_plus_pymaya.exp b/PYProjects/skin_plus_plus/dccs/maya/skin_plus_plus_pymaya_2023/skin_plus_plus_pymaya.exp
index 3feb3eb..702c2f4 100644
Binary files a/PYProjects/skin_plus_plus/dccs/maya/skin_plus_plus_pymaya_2023/skin_plus_plus_pymaya.exp and b/PYProjects/skin_plus_plus/dccs/maya/skin_plus_plus_pymaya_2023/skin_plus_plus_pymaya.exp differ
diff --git a/PYProjects/skin_plus_plus/dccs/maya/skin_plus_plus_pymaya_2023/skin_plus_plus_pymaya.pyd b/PYProjects/skin_plus_plus/dccs/maya/skin_plus_plus_pymaya_2023/skin_plus_plus_pymaya.pyd
index 4794a05..6f25b0e 100644
Binary files a/PYProjects/skin_plus_plus/dccs/maya/skin_plus_plus_pymaya_2023/skin_plus_plus_pymaya.pyd and b/PYProjects/skin_plus_plus/dccs/maya/skin_plus_plus_pymaya_2023/skin_plus_plus_pymaya.pyd differ
diff --git a/PYProjects/skin_plus_plus/dccs/maya/skin_plus_plus_pymaya_debug_2023/skin_plus_plus_pymaya.pyd b/PYProjects/skin_plus_plus/dccs/maya/skin_plus_plus_pymaya_debug_2023/skin_plus_plus_pymaya.pyd
new file mode 100644
index 0000000..e69de29
diff --git a/PYProjects/skin_plus_plus/py/39/skin_plus_plus_py.exp b/PYProjects/skin_plus_plus/py/39/skin_plus_plus_py.exp
index f870b25..3f0d760 100644
Binary files a/PYProjects/skin_plus_plus/py/39/skin_plus_plus_py.exp and b/PYProjects/skin_plus_plus/py/39/skin_plus_plus_py.exp differ
diff --git a/PYProjects/skin_plus_plus/py/39/skin_plus_plus_py.pyd b/PYProjects/skin_plus_plus/py/39/skin_plus_plus_py.pyd
index ec09a67..cb2ef9a 100644
Binary files a/PYProjects/skin_plus_plus/py/39/skin_plus_plus_py.pyd and b/PYProjects/skin_plus_plus/py/39/skin_plus_plus_py.pyd differ
diff --git a/PYProjects/skin_plus_plus/py/debug_39/skin_plus_plus_py.exp b/PYProjects/skin_plus_plus/py/debug_39/skin_plus_plus_py.exp
index bfbc911..52d98a5 100644
Binary files a/PYProjects/skin_plus_plus/py/debug_39/skin_plus_plus_py.exp and b/PYProjects/skin_plus_plus/py/debug_39/skin_plus_plus_py.exp differ
diff --git a/PYProjects/skin_plus_plus/py/debug_39/skin_plus_plus_py.pyd b/PYProjects/skin_plus_plus/py/debug_39/skin_plus_plus_py.pyd
index 9955bb8..d246c96 100644
Binary files a/PYProjects/skin_plus_plus/py/debug_39/skin_plus_plus_py.pyd and b/PYProjects/skin_plus_plus/py/debug_39/skin_plus_plus_py.pyd differ
diff --git a/PYProjects/skin_plus_plus_test/ordering_test.py b/PYProjects/skin_plus_plus_test/ordering_test.py
new file mode 100644
index 0000000..cdaa908
--- /dev/null
+++ b/PYProjects/skin_plus_plus_test/ordering_test.py
@@ -0,0 +1,58 @@
+from __future__ import annotations
+
+
+def get_flat_weights(bone_ids: list[list[int]], weights: list[list[float]], max_influence_count: int = 3):
+ vertex_count = len(bone_ids)
+ m_weights = [0.0] * vertex_count * max_influence_count
+ for vertex_index in range(vertex_count):
+ vertex_bone_ids = bone_ids[vertex_index]
+ array_index = vertex_index * max_influence_count
+ for influence_index in range(len(vertex_bone_ids)):
+ bone_id = vertex_bone_ids[influence_index]
+ if bone_id == -1:
+ continue
+ index = array_index + bone_id
+ m_weights[index] = weights[vertex_index][influence_index]
+
+ return m_weights
+
+names = ["one", "two", "three"]
+new_names = ["FART", "three", "one", "two", "RANDOM"]
+bone_ids = [[0, 1, -1], [-1, 1, 2], [0, 1, 2]]
+weights = [[0.25, 0.75, None], [None, 0.5, 0.5], [0.25, 0.25, 0.5]]
+
+m_weights = get_flat_weights(bone_ids, weights)
+
+print(m_weights)
+print(m_weights == [0.25, 0.75, 0.0, 0.0, 0.5, 0.5, 0.25, 0.25, 0.5])
+
+
+name_map = {}
+for index, name in enumerate(new_names):
+ name_map[name] = index
+
+new_bone_ids = []
+for name in names:
+ new_index = name_map[name]
+ new_bone_ids.append(new_index)
+
+def get_sorted_bone_ids(bone_ids: list[list[int]], new_bone_id_order: list[int]):
+ for vertex in bone_ids:
+ for i, bone_id in enumerate(vertex):
+ if bone_id == -1:
+ continue
+
+ new_index = new_bone_id_order[bone_id]
+ vertex[i] = new_index
+
+ return bone_ids
+
+
+sorted_bone_ids = get_sorted_bone_ids(bone_ids, new_bone_ids)
+print(bone_ids)
+print(bone_ids == [[1, 2, -1], [-1, 2, 0], [1, 2, 0]])
+
+m_weights = get_flat_weights(sorted_bone_ids, weights)
+
+print(m_weights)
+print(m_weights == [0.0, 0.25, 0.75, 0.5, 0.0, 0.5, 0.5, 0.25, 0.25])
diff --git a/PYProjects/skin_plus_plus_test/skin_plus_plus_test.py b/PYProjects/skin_plus_plus_test/skin_plus_plus_test.py
index 9c27ed6..c34287e 100644
--- a/PYProjects/skin_plus_plus_test/skin_plus_plus_test.py
+++ b/PYProjects/skin_plus_plus_test/skin_plus_plus_test.py
@@ -1,14 +1,9 @@
from __future__ import annotations
-import functools
+
import inspect
-import numpy as np
import pathlib
-import random
import site
-import sys
-import time
-import unittest
if __name__ == "__main__":
@@ -24,15 +19,23 @@ def __setup__():
__setup__()
+import functools
+import numpy as np
+import random
+import sys
+import time
+import unittest
+
+
import skin_plus_plus
# skin_plus_plus.set_debug(False)
if __name__ == "__main__":
from importlib import reload
- reload(skin_plus_plus.core)
- reload(skin_plus_plus.io)
- reload(skin_plus_plus)
+ # reload(skin_plus_plus.core)
+ # reload(skin_plus_plus.io)
+ # reload(skin_plus_plus)
_typing = False
if _typing:
@@ -673,9 +676,39 @@ def add_bones():
if __name__ == "__main__":
- skin_plus_plus.io.max_to_maya(file_type=skin_plus_plus.FileType.pickle)
+ pass
+ # skin_plus_plus.io.max_to_maya(file_type=skin_plus_plus.FileType.pickle)
+ # skin_plus_plus
+ # bones = ["one", "two"]
+ # ids = np.array([[0, 1], [1, 0]], dtype=np.float64)
+ # weights = np.array([[0.25, 0.75], [0.25, 0.75]], dtype=np.float64)
+ # pos = np.array([[0.1, 0.75, 2.0], [0.25, 0.75, 30]], dtype=np.float64)
+ # sd = skin_plus_plus.skin_plus_plus_py.SkinData(bones, ids, weights, pos)
+ # print(sd)
+
+ # print(sd.bone_ids)
# skin_plus_plus.io.save(file_type=skin_plus_plus.FileType.json)
- skin_plus_plus.io.load(file_type=skin_plus_plus.FileType.json)
+ # skin_plus_plus.io.load(file_type=skin_plus_plus.FileType.json)
+ import json
+ import pickle
+
+ path = r""
+
+ with open(path, "r") as file:
+ data = json.load(file)
+ skin_data = skin_plus_plus.SkinData(
+ tuple(data["bone_names"]),
+ tuple(data["bone_ids"]),
+ tuple(data["weights"]),
+ tuple(data["positions"])
+ )
+ # with open(path, "rb") as file:
+ # skin_data = pickle.load(file)
+
+ print(skin_data)
+ # for ids in skin_data.bone_ids:
+ # print(ids)
+ skin_plus_plus.set_skin_weights("Skeleton", skin_data)
# skin_data = skin_plus_plus.get_skin_data("Weapon_Shield_1H_001_Model_Main_01_:Shield_GEO")
# print(skin_data)
# skin_plus_plus.set_skin_weights("SM_EliteEnemy_Axe_GEO", skin_data)
diff --git a/PYProjects/source/skin_plus_plus_py/headers/skin_plus_plus_py.h b/PYProjects/source/skin_plus_plus_py/headers/skin_plus_plus_py.h
index 6c4e5d7..a38172f 100644
--- a/PYProjects/source/skin_plus_plus_py/headers/skin_plus_plus_py.h
+++ b/PYProjects/source/skin_plus_plus_py/headers/skin_plus_plus_py.h
@@ -105,8 +105,8 @@ struct PySkinData final
PySkinData(UINT vertexCount, UINT maxInfluenceCount)
{
- this->boneIDs = BoneIDsMatrix(vertexCount, maxInfluenceCount);
- this->weights = WeightsMatrix(vertexCount, maxInfluenceCount);
+ this->boneIDs = BoneIDsMatrix::Constant(vertexCount, maxInfluenceCount, -1);
+ this->weights = WeightsMatrix::Zero(vertexCount, maxInfluenceCount);
this->positions = PositionMatrix(vertexCount, 3);
}
@@ -142,8 +142,8 @@ struct PySkinData final
// Set a new maximum influence count
void setMaximumVertexWeightCount(int influenceCount)
{
- this->boneIDs.resize(eg::NoChange, influenceCount);
- this->weights.resize(eg::NoChange, influenceCount);
+ this->boneIDs.conservativeResize(eg::NoChange, influenceCount);
+ this->weights.conservativeResize(eg::NoChange, influenceCount);
}
// Get the bone ids in their correct order as well as any missing bones
diff --git a/PYProjects/source/skin_plus_plus_py/skin_plus_plus_py.vcxproj b/PYProjects/source/skin_plus_plus_py/skin_plus_plus_py.vcxproj
index d2b4621..063fdd6 100644
--- a/PYProjects/source/skin_plus_plus_py/skin_plus_plus_py.vcxproj
+++ b/PYProjects/source/skin_plus_plus_py/skin_plus_plus_py.vcxproj
@@ -47,9 +47,9 @@
DynamicLibrary
- false
+ true
v142
- true
+ false
Unicode
@@ -90,7 +90,7 @@
false
.pyd
- $(SolutionDir)..\..\PYProjects\skin_plus_plus\py\39
+ $(SolutionDir)..\..\PYProjects\skin_plus_plus\py\39\
$(THIRD_PARTY_EIGEN);$(THIRD_PARTY_FMT)\include;$(ProjectDir)headers;$(PYTHON_39)\include;$(PYBIND11_39)\include;$(IncludePath)
diff --git a/PYProjects/source/skin_plus_plus_pymaya/skin_plus_plus_pymaya.cpp b/PYProjects/source/skin_plus_plus_pymaya/skin_plus_plus_pymaya.cpp
index 8038338..ffc3f50 100644
--- a/PYProjects/source/skin_plus_plus_pymaya/skin_plus_plus_pymaya.cpp
+++ b/PYProjects/source/skin_plus_plus_pymaya/skin_plus_plus_pymaya.cpp
@@ -248,6 +248,63 @@ PySkinData SkinManagerMaya::getData()
}
+
+void sortBoneIDs(BoneIDsMatrix& boneIDs, std::vector newIDOrder, const int vertexCount, const int influenceCount)
+{
+ BoneIDsMatrix sortedBoneIDs = BoneIDsMatrix(boneIDs);
+ for (size_t vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++)
+ {
+ for (size_t influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++)
+ {
+ const int boneID = boneIDs(vertexIndex, influenceIndex);
+ if (boneID == -1)
+ {
+ continue;
+ }
+ const int newIndex = newIDOrder[boneID];
+ boneIDs(vertexIndex, influenceIndex) = newIndex;
+ }
+ }
+}
+
+///
+/// Convert an eigen::MatrixXd weights matrix to a MDoubleArray.
+/// This array is flat, so the weights which are passed in as a vertex count x influence count matrix, need to be
+/// structured so they are flat but each number of elements in the array still represents vertex count x influence count.
+///
+/// For example:
+/// matrix[0][3] == MDoubleArray[3]
+/// matrix[3][3] == MDoubleArray[9]
+///
+///
+///
+///
+///
+///
+///
+MDoubleArray getWeightsAsMDoubleArray(BoneIDsMatrix boneIDs, WeightsMatrix weights, const int vertexCount, const int influenceCount)
+{
+ const UINT arraySize = vertexCount * influenceCount;
+ MDoubleArray mWeights(arraySize);
+ for (size_t vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++)
+ {
+ const int baseIndex = vertexIndex * influenceCount;
+ for (size_t influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++)
+ {
+ const int boneID = boneIDs(vertexIndex, influenceIndex);
+ if (boneID == -1)
+ {
+ continue;
+ }
+ double weight = weights(vertexIndex, influenceIndex);
+ const UINT mWeightsIndex = baseIndex + boneID;
+ mWeights[mWeightsIndex] = weight;
+ }
+ }
+ return mWeights;
+}
+
+
bool SkinManagerMaya::setSkinWeights(PySkinData& skinData)
{
auto vertexCount = skinData.boneIDs.rows();
@@ -284,13 +341,13 @@ bool SkinManagerMaya::setSkinWeights(PySkinData& skinData)
{
throw std::exception("Error querying bones!");
}
- auto skinBoneCount = skinnedBones.length();
- auto currentBoneNames = std::vector(skinBoneCount);
- for (UINT boneIndex = 0; boneIndex < skinBoneCount; boneIndex++)
+ auto skinnedBoneCount = skinnedBones.length();
+ auto currentBoneNames = std::vector(skinnedBoneCount);
+ for (UINT boneIndex = 0; boneIndex < skinnedBoneCount; boneIndex++)
{
currentBoneNames[boneIndex] = fmt::format("{}", skinnedBones[boneIndex].partialPathName().asChar());
}
- if (skinBoneCount == 0)
+ if (skinnedBoneCount == 0)
{
this->addMissingBones(skinData.boneNames, skinnedBones);
this->fnSkinCluster.influenceObjects(skinnedBones, &status);
@@ -301,36 +358,31 @@ bool SkinManagerMaya::setSkinWeights(PySkinData& skinData)
skinnedBones.clear();
this->addMissingBones(sortedBoneIDs.unfoundBoneNames, skinnedBones);
this->fnSkinCluster.influenceObjects(skinnedBones, &status);
+ auto sortedBoneIDs = skinData.getSortedBoneIDs(currentBoneNames);
}
//validateBindPose(bindPoseMembersArray, skinnedBones);
- auto arraySize = vertexCount * influenceCount;
- MIntArray mBoneIDs(influenceCount);
- MDoubleArray mWeights(arraySize);
- for (UINT influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++)
- {
- mBoneIDs[influenceIndex] = sortedBoneIDs.sortedBoneIDs[influenceIndex];
- }
- // Unpack nested arrays like so: [[0, 1], [2, 3]] -> [0, 1, 2, 3]
- for (UINT vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++)
- {
- UINT arrayIndex = vertexIndex * influenceCount;
- for (UINT influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++)
- {
- arrayIndex += influenceIndex;
- auto boneID = skinData.boneIDs(vertexIndex, influenceIndex);
- auto vertexWeight = skinData.weights(vertexIndex, influenceIndex);
- mWeights[arrayIndex] = vertexWeight;
- }
- }
- py::print("mWeights length: ", mWeights.length());
- for (UINT i = 0; i < mWeights.length(); i++)
+
+ MIntArray mBoneIDs(skinnedBoneCount);
+ auto sortedBoneSize = sortedBoneIDs.sortedBoneIDs.size();
+ //if (skinnedBoneCount != sortedBoneSize)
+ //{
+ // auto exceptionText = convertStringToChar(
+ // fmt::format(
+ // "Skinned bone count {} does not match sorted bone count {}",
+ // skinnedBoneCount,
+ // sortedBoneSize
+ // )
+ // );
+ // throw std::length_error(exceptionText);
+ //}
+ for (UINT index = 0; index < skinnedBoneCount; index++)
{
- py::print(mWeights[i]);
- py::print(mBoneIDs[i]);
- py::print("---");
+ mBoneIDs[index] = index;
}
+ sortBoneIDs(skinData.boneIDs, sortedBoneIDs.sortedBoneIDs, vertexCount, influenceCount);
+ MDoubleArray mWeights = getWeightsAsMDoubleArray(skinData.boneIDs, skinData.weights, vertexCount, influenceCount);
status = this->fnSkinCluster.setWeights(
this->dagPath,
this->component,
diff --git a/PYProjects/source/skin_plus_plus_pymaya/skin_plus_plus_pymaya.vcxproj b/PYProjects/source/skin_plus_plus_pymaya/skin_plus_plus_pymaya.vcxproj
index f6fa2f7..a377dcf 100644
--- a/PYProjects/source/skin_plus_plus_pymaya/skin_plus_plus_pymaya.vcxproj
+++ b/PYProjects/source/skin_plus_plus_pymaya/skin_plus_plus_pymaya.vcxproj
@@ -52,9 +52,9 @@
DynamicLibrary
- false
+ true
v142
- true
+ false
Unicode
x64
@@ -83,13 +83,13 @@
.pyd
$(THIRD_PARTY_EIGEN);$(THIRD_PARTY_FMT)\include;$(ProjectDir);$(ProjectDir)..\skin_plus_plus_py\headers;$(ADSK_MAYA_SDK_2022)\include;$(PYTHON_37)\include;
$(ADSK_MAYA_SDK_2022)\lib;$(PYTHON_37)\libs
- $(SolutionDir)..\..\PYProjects\skin_plus_plus\dccs\maya\$(ProjectName)_debug_2022
+ $(SolutionDir)..\..\PYProjects\skin_plus_plus\dccs\maya\$(ProjectName)_debug_2023\
true
.pyd
- $(THIRD_PARTY_EIGEN);$(THIRD_PARTY_FMT)\include;$(ProjectDir);$(ProjectDir)..\skin_plus_plus_py\headers;$(ADSK_MAYA_SDK_2023)\include;
- $(ADSK_MAYA_SDK_2023)\lib;C:\Program Files\Python39\libs
+ $(THIRD_PARTY_EIGEN);$(THIRD_PARTY_FMT)\include;$(ProjectDir);$(ProjectDir)..\skin_plus_plus_py\headers;$(ADSK_MAYA_SDK_2023)\include;$(PYTHON_39)\include;$(PYBIND11_39)\include;$(IncludePath)
+ $(ADSK_MAYA_SDK_2023)\lib;$(PYTHON_39)\libs;$(LibraryPath)
$(SolutionDir)..\..\PYProjects\skin_plus_plus\dccs\maya\$(ProjectName)_debug_2023
@@ -104,7 +104,7 @@
.pyd
$(THIRD_PARTY_EIGEN);$(THIRD_PARTY_FMT)\include;$(ProjectDir);$(ProjectDir)..\skin_plus_plus_py\headers;$(ADSK_MAYA_SDK_2023)\include;$(PYTHON_39)\include;$(PYBIND11_39)\include;$(IncludePath)
$(ADSK_MAYA_SDK_2023)\lib;$(PYTHON_39)\libs;$(LibraryPath)
- $(SolutionDir)..\..\PYProjects\skin_plus_plus\dccs\maya\$(ProjectName)_2023
+ $(SolutionDir)..\..\PYProjects\skin_plus_plus\dccs\maya\$(ProjectName)_2023\
true
@@ -132,8 +132,8 @@
true
_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
- stdcpp20
- stdc17
+ stdcpp14
+ Default
Console
diff --git a/PYProjects/source/skin_plus_plus_pymxs/skin_plus_plus_pymxs.vcxproj b/PYProjects/source/skin_plus_plus_pymxs/skin_plus_plus_pymxs.vcxproj
index 6f91373..8ad3dc1 100644
--- a/PYProjects/source/skin_plus_plus_pymxs/skin_plus_plus_pymxs.vcxproj
+++ b/PYProjects/source/skin_plus_plus_pymxs/skin_plus_plus_pymxs.vcxproj
@@ -60,7 +60,7 @@
DynamicLibrary
- false
+ true
v142
false
Unicode
diff --git a/PYProjects/source/skin_plus_plus_pymxs/source/skin_plus_plus_pymxs.cpp b/PYProjects/source/skin_plus_plus_pymxs/source/skin_plus_plus_pymxs.cpp
index 367654c..8a5935c 100644
--- a/PYProjects/source/skin_plus_plus_pymxs/source/skin_plus_plus_pymxs.cpp
+++ b/PYProjects/source/skin_plus_plus_pymxs/source/skin_plus_plus_pymxs.cpp
@@ -141,6 +141,12 @@ void SkinManager::collectWeightsAndBoneIDs(UINT vertexIndex)
int influenceBoneID = this->iSkinContextData->GetAssignedBone(vertexIndex, influenceIndex);
this->pySkinData->weights(vertexIndex, influenceIndex) = infuenceWeight;
this->pySkinData->boneIDs(vertexIndex, influenceIndex) = influenceBoneID;
+ /* if (vertexIndex == 0 && influenceIndex == 0)
+ {
+ py::print("infuenceWeight: ", infuenceWeight);
+ py::print("influenceBoneID: ", influenceBoneID);
+ py::print("this->pySkinData->boneID: ", this->pySkinData->boneIDs(vertexIndex, influenceIndex));
+ }*/
}
}
@@ -154,12 +160,34 @@ PySkinData* SkinManager::getData()
unsigned int vertexCount = iSkinContextData->GetNumPoints();
maximumVertexWeightCount = iSkinContextData->GetNumAssignedBones(0);
+ for (UINT i = 1; i < vertexCount; i++)
+ {
+ auto influenceCount = iSkinContextData->GetNumAssignedBones(i);
+ if (influenceCount > maximumVertexWeightCount)
+ {
+ maximumVertexWeightCount = influenceCount;
+ }
+ }
pySkinData = new PySkinData(vertexCount, maximumVertexWeightCount);
auto skinBoneCount = iSkin->GetNumBones();
pySkinData->boneNames = std::vector(skinBoneCount);
for (auto boneIndex = 0; boneIndex < skinBoneCount; boneIndex++)
{
- pySkinData->boneNames[boneIndex] = convertWCharToString(iSkin->GetBoneName(boneIndex));
+ auto boneName = iSkin->GetBoneName(boneIndex);
+ if (boneName == NULL)
+ {
+ auto bone = iSkin->GetBone(boneIndex);
+ boneName = bone->GetActualINode()->GetName();
+ if (boneName == NULL)
+ {
+ auto handle = bone->GetHandle();
+ auto exceptionText = convertStringToChar(
+ fmt::format("Name is NULL on skinned bone at index: {} with handle: {}", boneIndex + 1, handle)
+ );
+ throw std::exception(exceptionText);
+ }
+ }
+ pySkinData->boneNames[boneIndex] = convertWCharToString(boneName);
}
auto meshType = getMeshType(node);
if (meshType == 0)
@@ -301,6 +329,7 @@ bool SkinManager::setSkinWeights(PySkinData& skinData)
BoneData boneData = getBoneData(this->iSkin, skinBoneCount);
SortedBoneNameData sortedBoneIDs = skinData.getSortedBoneIDs(boneData.names);
Tab skinBones = boneData.nodes;
+ size_t sortedBoneIDCount = sortedBoneIDs.sortedBoneIDs.size();
if (sortedBoneIDs.unfoundBoneNames.size() > 0)
{
this->addMissingBones(sortedBoneIDs.unfoundBoneNames);
@@ -317,10 +346,30 @@ bool SkinManager::setSkinWeights(PySkinData& skinData)
weights.Resize(boneIDsCols);
for (auto influenceIndex = 0; influenceIndex < boneIDsCols; influenceIndex++)
{
- auto sortedBoneID = sortedBoneIDs.sortedBoneIDs[influenceIndex];
- auto boneID = skinData.boneIDs(vertexIndex, sortedBoneID);
- float influenceWeight = skinData.weights(vertexIndex, sortedBoneID);
- bones.Append(1, &skinBones[boneID]);
+ const int boneID = skinData.boneIDs(vertexIndex, influenceIndex);
+ if (boneID == -1)
+ {
+ // If boneID is -1, then there are no more influence weights for this vertex so break out of the loop.
+ break;
+ }
+ if (boneID > skinBoneCount)
+ {
+ continue;
+ }
+ if (boneID > sortedBoneIDCount)
+ {
+ auto exceptionText = convertStringToChar(
+ fmt::format(
+ "Influence ID {} is out of range of sorted bone count {}!",
+ boneID,
+ sortedBoneIDCount
+ )
+ );
+ throw std::length_error(exceptionText);
+ }
+ float influenceWeight = skinData.weights(vertexIndex, influenceIndex);
+ const UINT sortedBoneID = sortedBoneIDs.sortedBoneIDs[boneID];
+ bones.Append(1, &skinBones[sortedBoneID]);
weights.Append(1, &influenceWeight);
}