diff --git a/.gitignore b/.gitignore index 5d06dfc..677ca42 100644 --- a/.gitignore +++ b/.gitignore @@ -436,4 +436,7 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ -# End of https://www.toptal.com/developers/gitignore/api/c++,visualstudio,visualstudiocode,sublimetext \ No newline at end of file +# End of https://www.toptal.com/developers/gitignore/api/c++,visualstudio,visualstudiocode,sublimetext + + +PyModules/venv37/ diff --git a/3DsMax/.vs/Skin++/v16/.suo b/3DsMax/.vs/Skin++/v16/.suo deleted file mode 100644 index 4b0b797..0000000 Binary files a/3DsMax/.vs/Skin++/v16/.suo and /dev/null differ diff --git a/3DsMax/.vs/Skin++/v16/Browse.VC.db b/3DsMax/.vs/Skin++/v16/Browse.VC.db deleted file mode 100644 index 0b620fc..0000000 Binary files a/3DsMax/.vs/Skin++/v16/Browse.VC.db and /dev/null differ diff --git a/3DsMax/.vs/Skin++/v16/ipch/AutoPCH/4d66a6d92ed8ea4d/DLLENTRY.ipch b/3DsMax/.vs/Skin++/v16/ipch/AutoPCH/4d66a6d92ed8ea4d/DLLENTRY.ipch deleted file mode 100644 index 7ec870c..0000000 Binary files a/3DsMax/.vs/Skin++/v16/ipch/AutoPCH/4d66a6d92ed8ea4d/DLLENTRY.ipch and /dev/null differ diff --git a/3DsMax/.vs/Skin++/v16/ipch/AutoPCH/54610a7394448f6e/SKIN++.ipch b/3DsMax/.vs/Skin++/v16/ipch/AutoPCH/54610a7394448f6e/SKIN++.ipch deleted file mode 100644 index cef03e0..0000000 Binary files a/3DsMax/.vs/Skin++/v16/ipch/AutoPCH/54610a7394448f6e/SKIN++.ipch and /dev/null differ diff --git a/3DsMax/.vs/Skin++/v16/ipch/AutoPCH/ff7c0b7471bac9d6/SKIN++.ipch b/3DsMax/.vs/Skin++/v16/ipch/AutoPCH/ff7c0b7471bac9d6/SKIN++.ipch deleted file mode 100644 index a065a4e..0000000 Binary files a/3DsMax/.vs/Skin++/v16/ipch/AutoPCH/ff7c0b7471bac9d6/SKIN++.ipch and /dev/null differ diff --git a/3DsMax/RCa12060 b/3DsMax/RCa12060 deleted file mode 100644 index 1ffd4ce..0000000 Binary files a/3DsMax/RCa12060 and /dev/null differ diff --git a/3DsMax/RCa13176 b/3DsMax/RCa13176 deleted file mode 100644 index 1ffd4ce..0000000 Binary files a/3DsMax/RCa13176 and /dev/null differ diff --git a/3DsMax/Skin++.aps b/3DsMax/Skin++.aps deleted file mode 100644 index 9841c5c..0000000 Binary files a/3DsMax/Skin++.aps and /dev/null differ diff --git a/3DsMax/Skin++.cpp b/3DsMax/Skin++.cpp deleted file mode 100644 index cf97a18..0000000 --- a/3DsMax/Skin++.cpp +++ /dev/null @@ -1,102 +0,0 @@ -//**************************************************************************/ -// Copyright (c) 1998-2018 Autodesk, Inc. -// All rights reserved. -// -// Use of this software is subject to the terms of the Autodesk license -// agreement provided at the time of installation or download, or which -// otherwise accompanies this software in either electronic or hard copy form. -//**************************************************************************/ -// DESCRIPTION: Appwizard generated plugin -// AUTHOR: -//***************************************************************************/ - -#include "Skin++.h" - -#define SkinPlusPlus_CLASS_ID Class_ID(0x99f0ea10, 0x69916a18) - - -class SkinPlusPlus : public GUP -{ -public: - //Constructor/Destructor - SkinPlusPlus(); - virtual ~SkinPlusPlus(); - - // GUP Methods - virtual DWORD Start(); - virtual void Stop(); - virtual DWORD_PTR Control(DWORD parameter); - virtual void DeleteThis(); - - // Loading/Saving - virtual IOResult Save(ISave* isave); - virtual IOResult Load(ILoad* iload); -}; - - - -class SkinPlusPlusClassDesc : public ClassDesc2 -{ -public: - virtual int IsPublic() override { return TRUE; } - virtual void* Create(BOOL /*loading = FALSE*/) override { return new SkinPlusPlus(); } - virtual const TCHAR * ClassName() override { return GetString(IDS_CLASS_NAME); } - virtual SClass_ID SuperClassID() override { return GUP_CLASS_ID; } - virtual Class_ID ClassID() override { return SkinPlusPlus_CLASS_ID; } - virtual const TCHAR* Category() override { return GetString(IDS_CATEGORY); } - - virtual const TCHAR* InternalName() override { return _T("SkinPlusPlusUtility"); } // Returns fixed parsable name (scripter-visible name) - virtual HINSTANCE HInstance() override { return hInstance; } // Returns owning module handle - - -}; - -ClassDesc2* GetSkinPlusPlusDesc() -{ - static SkinPlusPlusClassDesc SkinPlusPlusDesc; - return &SkinPlusPlusDesc; -} - - - - -SkinPlusPlus::SkinPlusPlus() -{ - -} - -SkinPlusPlus::~SkinPlusPlus() -{ - -} - -void SkinPlusPlus::DeleteThis() -{ - delete this; -} - -// Activate and Stay Resident -DWORD SkinPlusPlus::Start() -{ - return GUPRESULT_KEEP; -} - -void SkinPlusPlus::Stop() -{ -} - -DWORD_PTR SkinPlusPlus::Control( DWORD /*parameter*/ ) -{ - return 0; -} - -IOResult SkinPlusPlus::Save(ISave* /*isave*/) -{ - return IO_OK; -} - -IOResult SkinPlusPlus::Load(ILoad* /*iload*/) -{ - return IO_OK; -} - diff --git a/3DsMax/Skin++.h b/3DsMax/Skin++.h deleted file mode 100644 index c7b7d56..0000000 --- a/3DsMax/Skin++.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -//**************************************************************************/ -// Copyright (c) 1998-2018 Autodesk, Inc. -// All rights reserved. -// -// Use of this software is subject to the terms of the Autodesk license -// agreement provided at the time of installation or download, or which -// otherwise accompanies this software in either electronic or hard copy form. -//**************************************************************************/ -// DESCRIPTION: Includes for Plugins -// AUTHOR: -//***************************************************************************/ - -#include -#pragma warning (disable : ALL_CODE_ANALYSIS_WARNINGS) - -#include "3dsmaxsdk_preinclude.h" -#include "resource.h" -#include -#include -#include -#include -//SIMPLE TYPE - - -#include - - -extern TCHAR *GetString(int id); - -extern HINSTANCE hInstance; - diff --git a/3DsMax/Skin++.vcxproj.user b/3DsMax/Skin++.vcxproj.user deleted file mode 100644 index 5d73326..0000000 --- a/3DsMax/Skin++.vcxproj.user +++ /dev/null @@ -1,18 +0,0 @@ - - - - $(ADSK_3DSMAX_x64_2021)\3dsmax.exe - $(ADSK_3DSMAX_x64_2021) - WindowsLocalDebugger - - - $(ADSK_3DSMAX_x64_2021)\3dsmax.exe - $(ADSK_3DSMAX_x64_2021) - WindowsLocalDebugger - - - $(ADSK_3DSMAX_x64_2021)\3dsmax.exe - $(ADSK_3DSMAX_x64_2021) - WindowsLocalDebugger - - \ No newline at end of file diff --git a/3DsMax/obj/x64/Debug/RCa16084 b/3DsMax/obj/x64/Debug/RCa16084 deleted file mode 100644 index 252efbb..0000000 Binary files a/3DsMax/obj/x64/Debug/RCa16084 and /dev/null differ diff --git a/3DsMax/obj/x64/Debug/Skin++.log b/3DsMax/obj/x64/Debug/Skin++.log deleted file mode 100644 index 2484fd0..0000000 --- a/3DsMax/obj/x64/Debug/Skin++.log +++ /dev/null @@ -1,9 +0,0 @@ - Skin++.cpp - DllEntry.cpp - d:\code\git\skin++\skin++\dllentry.cpp(78): TODO: Perform initialization here. - d:\code\git\skin++\skin++\dllentry.cpp(87): TODO: Perform un-initialization here. - d:\code\git\skin++\skin++\skin++.cpp(81): TODO: Do plugin initialization here - d:\code\git\skin++\skin++\skin++.cpp(82): TODO: Return if you want remain loaded or not - d:\code\git\skin++\skin++\skin++.cpp(88): TODO: Do plugin un-initialization here -Skin++.rc(10): fatal error RC1015: cannot open include file 'afxres.h'. - diff --git a/3DsMax/obj/x64/Debug/Skin++.tlog/CL.12700.write.1.tlog b/3DsMax/obj/x64/Debug/Skin++.tlog/CL.12700.write.1.tlog deleted file mode 100644 index 0077b69..0000000 Binary files a/3DsMax/obj/x64/Debug/Skin++.tlog/CL.12700.write.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Debug/Skin++.tlog/CL.command.1.tlog b/3DsMax/obj/x64/Debug/Skin++.tlog/CL.command.1.tlog deleted file mode 100644 index cae1793..0000000 Binary files a/3DsMax/obj/x64/Debug/Skin++.tlog/CL.command.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Debug/Skin++.tlog/CL.read.1.tlog b/3DsMax/obj/x64/Debug/Skin++.tlog/CL.read.1.tlog deleted file mode 100644 index abf8a44..0000000 Binary files a/3DsMax/obj/x64/Debug/Skin++.tlog/CL.read.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Debug/Skin++.tlog/Skin++.lastbuildstate b/3DsMax/obj/x64/Debug/Skin++.tlog/Skin++.lastbuildstate deleted file mode 100644 index d477dad..0000000 --- a/3DsMax/obj/x64/Debug/Skin++.tlog/Skin++.lastbuildstate +++ /dev/null @@ -1,2 +0,0 @@ -#TargetFrameworkVersion=v4.7:PlatformToolSet=v141:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native64Bit:WindowsTargetPlatformVersion=10.0.17134.0 -Debug|x64|D:\Code\Git\Skin++\Skin++\| diff --git a/3DsMax/obj/x64/Debug/Skin++.tlog/rc.command.1.tlog b/3DsMax/obj/x64/Debug/Skin++.tlog/rc.command.1.tlog deleted file mode 100644 index 46b134b..0000000 --- a/3DsMax/obj/x64/Debug/Skin++.tlog/rc.command.1.tlog +++ /dev/null @@ -1 +0,0 @@ -ÿþ \ No newline at end of file diff --git a/3DsMax/obj/x64/Debug/Skin++.tlog/rc.read.1.tlog b/3DsMax/obj/x64/Debug/Skin++.tlog/rc.read.1.tlog deleted file mode 100644 index 46b134b..0000000 --- a/3DsMax/obj/x64/Debug/Skin++.tlog/rc.read.1.tlog +++ /dev/null @@ -1 +0,0 @@ -ÿþ \ No newline at end of file diff --git a/3DsMax/obj/x64/Debug/Skin++.tlog/rc.write.1.tlog b/3DsMax/obj/x64/Debug/Skin++.tlog/rc.write.1.tlog deleted file mode 100644 index 46b134b..0000000 --- a/3DsMax/obj/x64/Debug/Skin++.tlog/rc.write.1.tlog +++ /dev/null @@ -1 +0,0 @@ -ÿþ \ No newline at end of file diff --git a/3DsMax/obj/x64/Debug/Skin++.tlog/unsuccessfulbuild b/3DsMax/obj/x64/Debug/Skin++.tlog/unsuccessfulbuild deleted file mode 100644 index e69de29..0000000 diff --git a/3DsMax/obj/x64/Debug/vc141.pdb b/3DsMax/obj/x64/Debug/vc141.pdb deleted file mode 100644 index dfecb83..0000000 Binary files a/3DsMax/obj/x64/Debug/vc141.pdb and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/RCa10268 b/3DsMax/obj/x64/Hybrid/RCa10268 deleted file mode 100644 index 252efbb..0000000 Binary files a/3DsMax/obj/x64/Hybrid/RCa10268 and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/RCa17844 b/3DsMax/obj/x64/Hybrid/RCa17844 deleted file mode 100644 index edf62c9..0000000 Binary files a/3DsMax/obj/x64/Hybrid/RCa17844 and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/RCa26712 b/3DsMax/obj/x64/Hybrid/RCa26712 deleted file mode 100644 index 252efbb..0000000 Binary files a/3DsMax/obj/x64/Hybrid/RCa26712 and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.Build.CppClean.log b/3DsMax/obj/x64/Hybrid/Skin++.Build.CppClean.log deleted file mode 100644 index 7b74a84..0000000 --- a/3DsMax/obj/x64/Hybrid/Skin++.Build.CppClean.log +++ /dev/null @@ -1,23 +0,0 @@ -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.obj -d:\code\git\skin++\skin++\obj\x64\hybrid\dllentry.obj -d:\code\git\skin++\skin++\obj\x64\hybrid\vc141.pdb -c:\program files\autodesk\3ds max 2021\plugins\skin++.ilk -c:\program files\autodesk\3ds max 2021\plugins\skin++.gup -c:\program files\autodesk\3ds max 2021\plugins\skin++.pdb -c:\program files\autodesk\3ds max 2021 sdk\maxsdk\pdb\x64\hybrid\skin++.pdb -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.res -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.lib -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.exp -c:\program files\autodesk\3ds max 2021\\plugins\skin++.pdb -c:\program files\autodesk\3ds max 2021\\plugins\skin++.gup -c:\program files\autodesk\3ds max 2021\\plugins\skin++.ilk -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.tlog\cl.2196.write.1.tlog -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.tlog\cl.command.1.tlog -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.tlog\cl.read.1.tlog -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.tlog\link.command.1.tlog -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.tlog\link.read.1.tlog -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.tlog\link.write.1.tlog -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.tlog\rc.command.1.tlog -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.tlog\rc.read.1.tlog -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.tlog\rc.write.1.tlog -d:\code\git\skin++\skin++\obj\x64\hybrid\skin++.tlog\skin++.write.1u.tlog diff --git a/3DsMax/obj/x64/Hybrid/Skin++.exp b/3DsMax/obj/x64/Hybrid/Skin++.exp deleted file mode 100644 index a1e9d44..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.exp and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.log b/3DsMax/obj/x64/Hybrid/Skin++.log deleted file mode 100644 index b0b7164..0000000 --- a/3DsMax/obj/x64/Hybrid/Skin++.log +++ /dev/null @@ -1,4 +0,0 @@ - Skin++.cpp - DllEntry.cpp - Creating library D:\Code\Git\SkinPlusPlus\3DsMax\\obj\x64\Hybrid\\Skin++.lib and object D:\Code\Git\SkinPlusPlus\3DsMax\\obj\x64\Hybrid\\Skin++.exp - Skin++.vcxproj -> D:\Code\Git\SkinPlusPlus\3DsMax\\output\Hybrid\Skin++.gup diff --git a/3DsMax/obj/x64/Hybrid/Skin++.res b/3DsMax/obj/x64/Hybrid/Skin++.res deleted file mode 100644 index 0694003..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.res and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.tlog/CL.24124.write.1.tlog b/3DsMax/obj/x64/Hybrid/Skin++.tlog/CL.24124.write.1.tlog deleted file mode 100644 index eb109b5..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.tlog/CL.24124.write.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.tlog/CL.command.1.tlog b/3DsMax/obj/x64/Hybrid/Skin++.tlog/CL.command.1.tlog deleted file mode 100644 index b7c008a..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.tlog/CL.command.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.tlog/CL.read.1.tlog b/3DsMax/obj/x64/Hybrid/Skin++.tlog/CL.read.1.tlog deleted file mode 100644 index 79eadbf..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.tlog/CL.read.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.tlog/Skin++.lastbuildstate b/3DsMax/obj/x64/Hybrid/Skin++.tlog/Skin++.lastbuildstate deleted file mode 100644 index ca7e882..0000000 --- a/3DsMax/obj/x64/Hybrid/Skin++.tlog/Skin++.lastbuildstate +++ /dev/null @@ -1,2 +0,0 @@ -#TargetFrameworkVersion=v4.7:PlatformToolSet=v141:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native64Bit:WindowsTargetPlatformVersion=10.0.17134.0 -Hybrid|x64|D:\Code\Git\SkinPlusPlus\3DsMax\| diff --git a/3DsMax/obj/x64/Hybrid/Skin++.tlog/Skin++.write.1u.tlog b/3DsMax/obj/x64/Hybrid/Skin++.tlog/Skin++.write.1u.tlog deleted file mode 100644 index f50a542..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.tlog/Skin++.write.1u.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.tlog/link.command.1.tlog b/3DsMax/obj/x64/Hybrid/Skin++.tlog/link.command.1.tlog deleted file mode 100644 index 066c23b..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.tlog/link.command.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.tlog/link.read.1.tlog b/3DsMax/obj/x64/Hybrid/Skin++.tlog/link.read.1.tlog deleted file mode 100644 index 042f86f..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.tlog/link.read.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.tlog/link.write.1.tlog b/3DsMax/obj/x64/Hybrid/Skin++.tlog/link.write.1.tlog deleted file mode 100644 index 4a9fd36..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.tlog/link.write.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.tlog/rc.command.1.tlog b/3DsMax/obj/x64/Hybrid/Skin++.tlog/rc.command.1.tlog deleted file mode 100644 index 7cb0e32..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.tlog/rc.command.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.tlog/rc.read.1.tlog b/3DsMax/obj/x64/Hybrid/Skin++.tlog/rc.read.1.tlog deleted file mode 100644 index 1450611..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.tlog/rc.read.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/Skin++.tlog/rc.write.1.tlog b/3DsMax/obj/x64/Hybrid/Skin++.tlog/rc.write.1.tlog deleted file mode 100644 index 6e9f545..0000000 Binary files a/3DsMax/obj/x64/Hybrid/Skin++.tlog/rc.write.1.tlog and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/dll/Skin++.gup b/3DsMax/obj/x64/Hybrid/dll/Skin++.gup deleted file mode 100644 index 57011e7..0000000 Binary files a/3DsMax/obj/x64/Hybrid/dll/Skin++.gup and /dev/null differ diff --git a/3DsMax/obj/x64/Hybrid/vc141.pdb b/3DsMax/obj/x64/Hybrid/vc141.pdb deleted file mode 100644 index 68b8ba0..0000000 Binary files a/3DsMax/obj/x64/Hybrid/vc141.pdb and /dev/null differ diff --git a/3DsMax/output/Hybrid/Skin++.gup b/3DsMax/output/Hybrid/Skin++.gup deleted file mode 100644 index ffbc3cd..0000000 Binary files a/3DsMax/output/Hybrid/Skin++.gup and /dev/null differ diff --git a/3DsMax/output/Hybrid/Skin++.ilk b/3DsMax/output/Hybrid/Skin++.ilk deleted file mode 100644 index 1f73dc9..0000000 Binary files a/3DsMax/output/Hybrid/Skin++.ilk and /dev/null differ diff --git a/3DsMax/output/Hybrid/Skin++.pdb b/3DsMax/output/Hybrid/Skin++.pdb deleted file mode 100644 index f7d3200..0000000 Binary files a/3DsMax/output/Hybrid/Skin++.pdb and /dev/null differ diff --git a/3DsMax/3dsmaxsdk_preinclude.h b/3dsmaxsdk_preinclude.h similarity index 100% rename from 3DsMax/3dsmaxsdk_preinclude.h rename to 3dsmaxsdk_preinclude.h diff --git a/3DsMax/DllEntry.cpp b/DllEntry.cpp similarity index 98% rename from 3DsMax/DllEntry.cpp rename to DllEntry.cpp index 2ba6313..eac783e 100644 --- a/3DsMax/DllEntry.cpp +++ b/DllEntry.cpp @@ -10,7 +10,7 @@ // AUTHOR: //***************************************************************************/ -#include "Skin++.h" +#include "SkinPlusPlus.h" extern ClassDesc2* GetSkinPlusPlusDesc(); @@ -27,7 +27,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID /*lpvReserved*/) { if (fdwReason == DLL_PROCESS_ATTACH) { - MaxSDK::Util::UseLanguagePackLocale(); // Hang on to this DLL's instance handle. hInstance = hinstDLL; DisableThreadLibraryCalls(hInstance); diff --git a/PyModules/create_venv.bat b/PyModules/create_venv.bat new file mode 100644 index 0000000..c03dd83 --- /dev/null +++ b/PyModules/create_venv.bat @@ -0,0 +1,4 @@ +py -3.7 -m venv venv37 +cd venv37/Scripts +activate & py -m pip install pybind11 & py -m pip pybind11 --includes +pause diff --git a/PyModules/skin_plus_plus/skin_plus_plus.sln b/PyModules/skin_plus_plus/skin_plus_plus.sln new file mode 100644 index 0000000..23ec854 --- /dev/null +++ b/PyModules/skin_plus_plus/skin_plus_plus.sln @@ -0,0 +1,43 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31702.278 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "skin_plus_plus_pymxs", "skin_plus_plus_pymxs\skin_plus_plus_pymxs.pyproj", "{E8B8F785-2830-442C-92F0-C9DD3291DB0E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SkinPlusPlusPymxs", "skin_plus_plus_pymxs\src\SkinPlusPlusPymxs\SkinPlusPlusPymxs.vcxproj", "{7BF5EA8D-2105-425A-967C-590AD47EC6CB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E8B8F785-2830-442C-92F0-C9DD3291DB0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E8B8F785-2830-442C-92F0-C9DD3291DB0E}.Debug|x64.ActiveCfg = Debug|Any CPU + {E8B8F785-2830-442C-92F0-C9DD3291DB0E}.Debug|x86.ActiveCfg = Debug|Any CPU + {E8B8F785-2830-442C-92F0-C9DD3291DB0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E8B8F785-2830-442C-92F0-C9DD3291DB0E}.Release|x64.ActiveCfg = Release|Any CPU + {E8B8F785-2830-442C-92F0-C9DD3291DB0E}.Release|x86.ActiveCfg = Release|Any CPU + {7BF5EA8D-2105-425A-967C-590AD47EC6CB}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {7BF5EA8D-2105-425A-967C-590AD47EC6CB}.Debug|x64.ActiveCfg = Debug|x64 + {7BF5EA8D-2105-425A-967C-590AD47EC6CB}.Debug|x64.Build.0 = Debug|x64 + {7BF5EA8D-2105-425A-967C-590AD47EC6CB}.Debug|x86.ActiveCfg = Debug|Win32 + {7BF5EA8D-2105-425A-967C-590AD47EC6CB}.Debug|x86.Build.0 = Debug|Win32 + {7BF5EA8D-2105-425A-967C-590AD47EC6CB}.Release|Any CPU.ActiveCfg = Release|Win32 + {7BF5EA8D-2105-425A-967C-590AD47EC6CB}.Release|x64.ActiveCfg = Release|x64 + {7BF5EA8D-2105-425A-967C-590AD47EC6CB}.Release|x64.Build.0 = Release|x64 + {7BF5EA8D-2105-425A-967C-590AD47EC6CB}.Release|x86.ActiveCfg = Release|Win32 + {7BF5EA8D-2105-425A-967C-590AD47EC6CB}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6267C530-5EEA-421D-9185-C6D78DC18581} + EndGlobalSection +EndGlobal diff --git a/PyModules/skin_plus_plus/skin_plus_plus_pymxs/skin_plus_plus_pymxs.py b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/skin_plus_plus_pymxs.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/skin_plus_plus_pymxs.py @@ -0,0 +1 @@ + diff --git a/PyModules/skin_plus_plus/skin_plus_plus_pymxs/skin_plus_plus_pymxs.pyproj b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/skin_plus_plus_pymxs.pyproj new file mode 100644 index 0000000..c7325c4 --- /dev/null +++ b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/skin_plus_plus_pymxs.pyproj @@ -0,0 +1,35 @@ + + + Debug + 2.0 + e8b8f785-2830-442c-92f0-c9dd3291db0e + . + skin_plus_plus_pymxs.py + + + . + . + skin_plus_plus_pymxs + skin_plus_plus_pymxs + + + true + false + + + true + false + + + + + + + + + + + + \ No newline at end of file diff --git a/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.cpp b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.cpp new file mode 100644 index 0000000..cc3c749 --- /dev/null +++ b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.cpp @@ -0,0 +1,251 @@ +#pragma once +#include + + +char convertWCharToChar(const wchar_t* text) +{ + size_t length = std::wcslen(text); + std::wstring_convert> conv; + std::string StoreTextBuffer = conv.to_bytes(text, text + length); + + return StoreTextBuffer[0]; +} + + +INode* getChildByName(const wchar_t* name, INode* parent) +{ + INode* parent_ = parent; + if (!parent) + { + Interface* ip = GetCOREInterface(); + parent_ = ip->GetRootNode(); + } + INode* node; + const wchar_t* nodeName; + for (int i = 0; i < parent_->NumberOfChildren(); i++) + { + node = parent_->GetChildNode(i); + nodeName = node->GetName(); + if (wcscmp(nodeName, name) == 0) return node; + try { node = getChildByName(name, parent = node); } catch (const std::invalid_argument&) { continue; } + return node; + } + //name->length(); + throw std::invalid_argument("No node with name: " + convertWCharToChar(name)); +} + + +bool SkinData::initialise(const wchar_t* name) +{ + this->node = getChildByName(name, NULL); + if (!this->node) + { + throw pybind11::type_error("SkinData init failed. No node with name: " + convertWCharToChar(name)); + } + Object* object = this->node->GetObjectRef(); + if (!object || (object->SuperClassID() != GEN_DERIVOB_CLASS_ID)) + { + throw pybind11::type_error("SkinData init failed. Node is incorrect type " + convertWCharToChar(this->node->GetName())); + } + this->iDerivedObject = (IDerivedObject*)(object); + if (!this->iDerivedObject) + { + this->isValid = false; + return this->isValid; + } + + for (int modifierIndex = 0; modifierIndex < this->iDerivedObject->NumModifiers(); modifierIndex++) + { + this->skinModifier = this->iDerivedObject->GetModifier(modifierIndex); + if (this->skinModifier->ClassID() != SKIN_CLASSID) continue; + + this->iSkin = (ISkin*)this->skinModifier->GetInterface(I_SKIN); + if (!this->iSkin) continue; + + this->iSkinContextData = this->iSkin->GetContextInterface(this->node); + if (!this->iSkinContextData) continue; + + this->iSkinImportData = (ISkinImportData*)this->skinModifier->GetInterface(I_SKINIMPORTDATA); + if (!this->iSkinImportData) continue; + + this->isValid = true; + return this->isValid; + } + throw std::exception("SkinData init failed on node: " + convertWCharToChar(name)); +} + + +std::vector>> SkinData::getSkinWeights() +{ + if (!this->isValid) + { + throw std::exception("SkinData object is invalid. Cannot get skin weights."); + } + unsigned int vertexCount = this->iSkinContextData->GetNumPoints(); + std::vector>> skinDataArray( + 2, std::vector>(vertexCount) + ); + //SkinArray skinDataArray(2, VertexArray(vertexCount)); + for (unsigned int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) + { + int16_t influenceCount = this->iSkinContextData->GetNumAssignedBones(vertexIndex); + std::vector influenceWeights(influenceCount); + std::vector influenceBoneIDs(influenceCount); + //influenceWeights[0] = 1.0f; + //influenceWeights->data()[0] = 1.0f; + skinDataArray[0][vertexIndex] = influenceWeights; //influenceWeights + skinDataArray[1][vertexIndex] = influenceBoneIDs; //influenceBoneIDs + for (int influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++) + { + float infuenceWeight = this->iSkinContextData->GetBoneWeight(vertexIndex, influenceIndex); + if (infuenceWeight <= 0.0f) continue; + int influenceBoneID = this->iSkinContextData->GetAssignedBone(vertexIndex, influenceIndex); + influenceWeights[influenceIndex] = infuenceWeight; + influenceBoneIDs[influenceIndex] = float(influenceBoneID); + } + }; + return skinDataArray; +} + +auto SkinData::getSkinWeightsPy(const int flag) +{ + auto weights = this->getSkinWeights(); + switch (flag) { + case 0: + { + py::array npArray = py::cast(weights); + return npArray; + } + case 1: + { + py::array npArray = py::cast(weights); + return npArray; + } + default: + { + py::array npArray = py::cast(weights); + return npArray; + } + } +} + + +inline std::vector>> getSkinWeights(wchar_t* name) +{ + SkinData* skinData = new SkinData(name); + return skinData->getSkinWeights(); +} + + +template +inline py::array_t as_pyarray(Sequence&& seq) { + auto size = seq.size(); + auto data = seq.data(); + std::unique_ptr seq_ptr = std::make_unique(std::move(seq)); + auto capsule = py::capsule(seq_ptr.get(), [](void* p) { std::unique_ptr(reinterpret_cast(p)); }); + seq_ptr.release(); + return py::array(size, data, capsule); +} + + +template +inline py::array_t>> as_pyfloatarray(Sequence&& seq) { + auto size = seq.size(); + auto data = seq.data(); + std::unique_ptr seq_ptr = std::make_unique(std::move(seq)); + auto capsule = py::capsule(seq_ptr.get(), [](void* p) { std::unique_ptr(reinterpret_cast(p)); }); + seq_ptr.release(); + return py::array(size, data, capsule); +} + +//template +//inline py::array_t asNestedPyArray(Sequence&& seq) { +// +//} + + + + +PYBIND11_MODULE(SkinPlusPlusPymxs, m) { + + py::class_(m, "SkinData") + .def(py::init<>()) + .def(py::init()) + .def("initialise", &SkinData::initialise) + .def("get_skin_weights", &SkinData::getSkinWeightsPy) + ; + + m.def("get_skin_weights", [&](wchar_t* name) { + std::vector>> weights = getSkinWeights(name); + return py::cast(weights); + }, "Get Skin Weights", + py::arg("name") + ); + m.def( + "get_skin_weights_np", [&](wchar_t* name) { + std::vector>> weights = getSkinWeights(name); + py::array npArray = py::cast(weights); + return npArray; + }, "Get Skin Weights as a numpy array", + py::arg("name") + ); + m.def("get_skin_weights_np_move", [&](wchar_t* name) { + std::vector>> weights = getSkinWeights(name); + py::array npArray = py::cast(weights, py::return_value_policy::move); + return npArray; + }, "Get Skin Weights as a numpy array", + py::arg("name") + ); + m.def("get_skin_weights_np_take_ownership", [&](wchar_t* name) { + std::vector>> weights = getSkinWeights(name); + py::array npArray = py::cast(weights, py::return_value_policy::take_ownership); + return npArray; + }, "Get Skin Weights as a numpy array", + py::arg("name") + ); + m.def("get_skin_weights_np_take_ownership", [&](wchar_t* name) { + std::vector>> weights = getSkinWeights(name); + py::array npArray = py::cast(weights, py::return_value_policy::take_ownership); + return npArray; + }, "Get Skin Weights as a numpy array", + py::arg("name") + ); + //m.def("f", []() { + // // Allocate and initialize some data; make this big so + // // we can see the impact on the process memory use: + // constexpr size_t size = 100 * 1000 * 1000; + // double* foo = new double[size]; + // for (size_t i = 0; i < size; i++) { + // foo[i] = (double)i; + // } + + // // Create a Python object that will free the allocated + // // memory when destroyed: + // py::capsule free_when_done(foo, [](void* f) { + // double* foo = reinterpret_cast(f); + // std::cerr << "Element [0] = " << foo[0] << "\n"; + // std::cerr << "freeing memory @ " << f << "\n"; + // delete[] foo; + // }); + + // return py::array_t( + // { 100, 1000, 1000 }, // shape + // { 1000 * 1000 * 8, 1000 * 8, 8 }, // C-style contiguous strides for double + // foo, // the data pointer + // free_when_done // numpy array references this parent + // ); + // } + //); + //m.def("f", [&](wchar_t* name) { + // std::vector>> weights = getSkinWeights(name); + // py::print(weights[0].size()); + // py::array_t>({ 2, weights[0].size() }, weights[0]) + // + // return py::array_t>>( + // { 2, weights[0].size() }, // shape + // { 1000 * 1000 * 8, 1000 * 8, 8 }, // C-style contiguous strides for double + // weights // the data pointer + // ); + // } + //); +} \ No newline at end of file diff --git a/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.h b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.h new file mode 100644 index 0000000..bf3a411 --- /dev/null +++ b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + + +namespace py = pybind11; + + +//typedef std::vector>> SkinDataVector_T; + +//using ValueArray = std::vector ; +//using VertexArray = std::vector ; +//using SkinArray = std::vector ; + + +class SkinData +{ +protected: + // Properties: + bool isValid = false; + INode* node; + IDerivedObject* iDerivedObject; + Modifier* skinModifier; + ISkin* iSkin; + ISkinContextData* iSkinContextData; // used to query skin data + ISkinImportData* iSkinImportData; // used to modify skin data + +public: + SkinData() {}; + SkinData(const wchar_t* name) { this->initialise(name); } + ~SkinData(){} + bool initialise(const wchar_t* name); + std::vector>> getSkinWeights(); + auto getSkinWeightsPy(const int flag); + auto getSkinWeights2(); + bool setSkinWeights(Array* boneIDs, Array* vertexWeights, Array* vertices = NULL); + bool setVertexWeights(int vertexIndex, Array* vertexBones, Array* vertexWeights); + bool setVertexWeights(const int vertexIndex, Array* inBoneIDs, Array* inVertexWeights, Tab inSkinBones); +}; \ No newline at end of file diff --git a/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.vcxproj b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.vcxproj new file mode 100644 index 0000000..3d0fc5c --- /dev/null +++ b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.vcxproj @@ -0,0 +1,161 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {7bf5ea8d-2105-425a-967c-590ad47ec6cb} + SkinPlusPlusPymxs + 10.0.17134.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + DynamicLibrary + true + v141 + Unicode + + + DynamicLibrary + false + v141 + false + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + _SkinPlusPlus + .pyd + + + false + .pyd + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + C:\Program Files\Python37\include;$(ProjectDir)..\..\..\..\venv37\Lib\site-packages\pybind11\include;%(AdditionalIncludeDirectories) + MultiThreadedDLL + + + Console + true + C:\Program Files\Python37\libs;%(AdditionalLibraryDirectories) + + + + + Level4 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + C:\Program Files\Autodesk\3ds Max 2022 SDK\maxsdk\include;C:\Program Files\Python37\include;$(ProjectDir)..\..\..\..\venv37\Lib\site-packages\pybind11\include;$(ProjectDir);%(AdditionalIncludeDirectories) + $(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0;%(AdditionalUsingDirectories) + true + + + Console + true + true + true + C:\Program Files\Autodesk\3ds Max 2022 SDK\maxsdk\lib\x64\Release\;C:\Program Files\Python37\libs;%(AdditionalLibraryDirectories) + bmm.lib;core.lib;geom.lib;gfx.lib;mesh.lib;maxutil.lib;maxscrpt.lib;gup.lib;paramblk2.lib;%(AdditionalDependencies) + + + + + + + + + + + + \ No newline at end of file diff --git a/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.vcxproj.filters b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.vcxproj.filters new file mode 100644 index 0000000..fdbda74 --- /dev/null +++ b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/src/SkinPlusPlusPymxs/SkinPlusPlusPymxs.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/PyModules/skin_plus_plus/skin_plus_plus_pymxs/test/skin_plus_plus_pymxs_test.py b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/test/skin_plus_plus_pymxs_test.py new file mode 100644 index 0000000..5d69b56 --- /dev/null +++ b/PyModules/skin_plus_plus/skin_plus_plus_pymxs/test/skin_plus_plus_pymxs_test.py @@ -0,0 +1,12 @@ +import site +site.addsitedir(r"D:\Code\Git\SkinPlusPlus\PyModules\skin_plus_plus\x64\Release") + +import SkinPlusPlusPymxs + +print(SkinPlusPlusPymxs) + +weights = SkinPlusPlusPymxs.get_skin_weights("Sphere001") +print(type(weights)) +print(len(weights[0])) + +print(weights[0][0]) \ No newline at end of file diff --git a/SkinPlusPlus.cpp b/SkinPlusPlus.cpp new file mode 100644 index 0000000..8e58cc6 --- /dev/null +++ b/SkinPlusPlus.cpp @@ -0,0 +1,523 @@ +//**************************************************************************/ +// Copyright (c) 1998-2021 Autodesk, Inc. +// All rights reserved. +// +// Use of this software is subject to the terms of the Autodesk license +// agreement provided at the time of installation or download, or which +// otherwise accompanies this software in either electronic or hard copy form. +//**************************************************************************/ +// DESCRIPTION: Appwizard generated plugin +// AUTHOR: +//***************************************************************************/ + +#include "SkinPlusPlus.h" + +#define SkinPlusPlus_CLASS_ID Class_ID(0x5b374d7b, 0x68620ce) + + +class SkinPlusPlus : public GUP +{ +public: + //Constructor/Destructor + SkinPlusPlus(); + virtual ~SkinPlusPlus(); + + // GUP Methods + virtual DWORD Start(); + virtual void Stop(); + virtual DWORD_PTR Control(DWORD parameter); + virtual void DeleteThis(); + + // Loading/Saving + virtual IOResult Save(ISave* isave); + virtual IOResult Load(ILoad* iload); +}; + +class SkinPlusPlusClassDesc : public ClassDesc2 +{ +public: + virtual int IsPublic() override { return TRUE; } + virtual void* Create(BOOL /*loading = FALSE*/) override { return new SkinPlusPlus(); } + virtual const TCHAR * ClassName() override { return GetString(IDS_CLASS_NAME); } + virtual const MCHAR* NonLocalizedClassName() override { return GetString(IDS_CLASS_NAME); } + + virtual SClass_ID SuperClassID() override { return GUP_CLASS_ID; } + virtual Class_ID ClassID() override { return SkinPlusPlus_CLASS_ID; } + virtual const TCHAR* Category() override { return GetString(IDS_CATEGORY); } + + virtual const TCHAR* InternalName() override { return _T("SkinPlusPlus"); } // Returns fixed parsable name (scripter-visible name) + virtual HINSTANCE HInstance() override { return hInstance; } // Returns owning module handle + + +}; + +ClassDesc2* GetSkinPlusPlusDesc() +{ + static SkinPlusPlusClassDesc SkinPlusPlusDesc; + return &SkinPlusPlusDesc; +} + +SkinPlusPlus::SkinPlusPlus() +{ + +} + +SkinPlusPlus::~SkinPlusPlus() +{ + +} + +void SkinPlusPlus::DeleteThis() +{ + delete this; +} + +// Activate and Stay Resident +DWORD SkinPlusPlus::Start() +{ + return GUPRESULT_KEEP; +} + +void SkinPlusPlus::Stop() +{ +} + +DWORD_PTR SkinPlusPlus::Control( DWORD /*parameter*/ ) +{ + return 0; +} + +IOResult SkinPlusPlus::Save(ISave* /*isave*/) +{ + return IO_OK; +} + +IOResult SkinPlusPlus::Load(ILoad* /*iload*/) +{ + return IO_OK; +} + + +// VertexData Methods: + +VertexData::VertexData(int vertexID, Array* boneIDs, Array* weights, Tab skinBones) +{ + if (!(boneIDs->size == weights->size)) + throw RuntimeError(_T("ids count does not match weights count"), Integer::intern(vertexID)); + + this->initialiseVariables(boneIDs->size); + float weightCap = 1.0f; + for (int vertexBoneIndex = 0; vertexBoneIndex < boneIDs->size; vertexBoneIndex++) + { + float weight = weights->data[vertexBoneIndex]->to_float(); + const int vertexBoneID = boneIDs->data[vertexBoneIndex]->to_int(); + INode* vertexBoneIDNode = skinBones[vertexBoneID - 1]; + if (weight < 0.0f) continue; + this->bones.Append(1, &vertexBoneIDNode); + if (weight > 1.0f) this->weights.Append(1, &weightCap); else this->weights.Append(1, &weight); + } +}; + +void VertexData::initialiseVariables(int size) +{ + this->bones = Tab(); + this->weights = Tab(); + this->bones.Resize(size); + this->weights.Resize(size); + +} + +void VertexData::appendVariables(INode* bone, float weight) +{ + this->bones.Append(1, &bone); + this->weights.Append(1, &weight); +} + + + //SkinData Methods: + +bool SkinData::initialise(INode* skinnedNode) +{ + this->allVertexData = Tab(); + this->node = skinnedNode; + Object* object = this->node->GetObjectRef(); + if (!object || (object->SuperClassID() != GEN_DERIVOB_CLASS_ID)) + { + return false; + } + this->iDerivedObject = (IDerivedObject*)(object); + if (!this->iDerivedObject) return false; + + for (int modifierIndex = 0; modifierIndex < this->iDerivedObject->NumModifiers(); modifierIndex++) + { + this->skinModifier = this->iDerivedObject->GetModifier(modifierIndex); + if (this->skinModifier->ClassID() != SKIN_CLASSID) continue; + + this->iSkin = (ISkin*)this->skinModifier->GetInterface(I_SKIN); + if (!this->iSkin) continue; + + this->iSkinContextData = this->iSkin->GetContextInterface(skinnedNode); + if (!this->iSkinContextData) continue; + + this->iSkinImportData = (ISkinImportData*)this->skinModifier->GetInterface(I_SKINIMPORTDATA); + if (!this->iSkinImportData) continue; + + return true; + } + return false; +} + +void SkinData::getSkinWeights(Array& ioSkinData) +{ + int vertexCount = this->iSkinContextData->GetNumPoints(); + ScopedMaxScriptEvaluationContext scopedMaxScriptEvaluationContext; + MAXScript_TLS* _tls = scopedMaxScriptEvaluationContext.Get_TLS(); + four_typed_value_locals_tls(Array* weights, Array* boneIDs, Array* influenceWeights, Array* influenceBoneIDs); + vl.weights = new Array(vertexCount); + vl.boneIDs = new Array(vertexCount); + vl.weights->size = vertexCount; + vl.boneIDs->size = vertexCount; + for (int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) + { + int influenceCount = this->iSkinContextData->GetNumAssignedBones(vertexIndex); + vl.influenceWeights = new Array(influenceCount); + vl.influenceBoneIDs = new Array(influenceCount); + vl.influenceWeights->size = influenceCount; + vl.influenceBoneIDs->size = influenceCount; + for (int influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++) + { + float infuenceWeight = this->iSkinContextData->GetBoneWeight(vertexIndex, influenceIndex); + int influenceBoneID = this->iSkinContextData->GetAssignedBone(vertexIndex, influenceIndex) + 1; + vl.influenceWeights->data[influenceIndex] = Float::intern(infuenceWeight); + vl.influenceBoneIDs->data[influenceIndex] = Integer::intern(influenceBoneID); + } + vl.weights->data[vertexIndex] = vl.influenceWeights; + vl.boneIDs->data[vertexIndex] = vl.influenceBoneIDs; + }; + ioSkinData.data[0] = vl.weights; + ioSkinData.data[1] = vl.boneIDs; +} + +Array* SkinData::getSkinWeights() +{ + int vertexCount = this->iSkinContextData->GetNumPoints(); + ScopedMaxScriptEvaluationContext scopedMaxScriptEvaluationContext; + MAXScript_TLS* _tls = scopedMaxScriptEvaluationContext.Get_TLS(); + five_typed_value_locals_tls( + Array* skinData, Array* weights, Array* boneIDs, Array* influenceWeights, Array* influenceBoneIDs + ); + vl.weights = new Array(vertexCount); + vl.boneIDs = new Array(vertexCount); + vl.weights->size = vertexCount; + vl.boneIDs->size = vertexCount; + for (int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) + { + int influenceCount = this->iSkinContextData->GetNumAssignedBones(vertexIndex); + vl.influenceWeights = new Array(influenceCount); + vl.influenceBoneIDs = new Array(influenceCount); + vl.influenceWeights->size = influenceCount; + vl.influenceBoneIDs->size = influenceCount; + for (int influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++) + { + float infuenceWeight = this->iSkinContextData->GetBoneWeight(vertexIndex, influenceIndex); + int influenceBoneID = this->iSkinContextData->GetAssignedBone(vertexIndex, influenceIndex) + 1; + vl.influenceWeights->data[influenceIndex] = Float::intern(infuenceWeight); + vl.influenceBoneIDs->data[influenceIndex] = Integer::intern(influenceBoneID); + } + vl.weights->data[vertexIndex] = vl.influenceWeights; + vl.boneIDs->data[vertexIndex] = vl.influenceBoneIDs; + }; + vl.skinData = new Array(2); + vl.skinData->size = 2; + vl.skinData->data[0] = vl.weights; + vl.skinData->data[1] = vl.boneIDs; + return_value_tls(vl.weights); +} + +bool SkinData::setVertexWeights(int vertexIndex, Array* vertexBones, Array* vertexWeights) +{ + if (!(vertexWeights->size == vertexBones->size)) + throw RuntimeError(_T("ids count does not match weights count"), (Value*)this->node); + + VertexData* vertexData = new VertexData(vertexWeights->size); + for (int vertexBoneIndex = 0; vertexBoneIndex < vertexWeights->size; vertexBoneIndex++) + { + float weight = vertexWeights->data[vertexBoneIndex]->to_float(); + if (weight <= 0.0f) continue; + if (weight > 1.0f) weight = 1.0f; + MAXNode* mxsVertexBoneIDNode = (MAXNode*)vertexBones->data[vertexBoneIndex]; + vertexData->appendVariables(mxsVertexBoneIDNode->to_node(), weight); + } + bool result = this->iSkinImportData->AddWeights(this->node, vertexIndex, vertexData->getBones(), vertexData->getWeights()); + this->skinModifier->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE); + GetCOREInterface()->RedrawViews(GetCOREInterface()->GetTime()); + + return result; +} + +bool SkinData::setVertexWeights(const int vertexIndex, Array* boneIDs, Array* vertexWeights, Tab skinBones) +{ + Array* vertexBoneIDs = (Array*)boneIDs->data[vertexIndex]; + Array* vertexBoneWeights = (Array*)vertexWeights->data[vertexIndex]; + VertexData* vertexData = new VertexData(vertexIndex, vertexBoneIDs, vertexBoneWeights, skinBones); + return this->iSkinImportData->AddWeights(this->node, vertexIndex, vertexData->getBones(), vertexData->getWeights()); +} + +bool SkinData::setSkinWeights(Array* boneIDs, Array* vertexWeights, Array* vertices) +{ + const int bonesArraySize = boneIDs->size; + const int weightsArraySize = vertexWeights->size; + if (bonesArraySize != weightsArraySize) throw RuntimeError( + _T("skin bone ids count does not match skin weights count"), (Value*)this->node + ); + Tab skinBones; + int skinBonesCount = this->iSkin->GetNumBones(); + for (int boneIndex = 0; boneIndex < skinBonesCount; boneIndex++) + { + INode* bone = this->iSkin->GetBone(boneIndex); + if (boneIndex == 0) + { + skinBones.Append(1, &bone, skinBonesCount); + continue; + } + skinBones.Append(1, &bone); + } + bool skinWeightsSet = true; + const int vertexCount = this->iSkinContextData->GetNumPoints(); + for (int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) + { + Array* vertexBoneIDs = (Array*)boneIDs->data[vertexIndex]; + Array* vertexBoneWeights = (Array*)vertexWeights->data[vertexIndex]; + VertexData* vertexData = new VertexData(vertexIndex, vertexBoneIDs, vertexBoneWeights, skinBones); + if (!(this->iSkinImportData->AddWeights(this->node, vertexIndex, vertexData->getBones(), vertexData->getWeights()))) + skinWeightsSet = false; + } + + this->skinModifier->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE); + GetCOREInterface()->RedrawViews(GetCOREInterface()->GetTime()); + return skinWeightsSet; +} + + +// SkinData Functions: + +void getSkinWeightsFn(INode* node, Array& ioSkinData) +{ + SkinData* skinData = new SkinData(node); + skinData->getSkinWeights(ioSkinData); +} + +Array* getSkinWeightsFn(INode* node) +{ + SkinData* skinData = new SkinData(node); + return skinData->getSkinWeights(); +} + +bool setVertexWeights(INode* node, int vertexIndex, Array* weightData) +{ + SkinData* skinData = new SkinData(node); + return skinData->setVertexWeights(vertexIndex, (Array*)weightData->data[0], (Array*)weightData->data[1]); +} + +bool setSkinWeightsFn(INode* node, Array* boneIDs, Array* vertexWeights, Array* vertices) +{ + SkinData* skinData = new SkinData(node); + return skinData->setSkinWeights(boneIDs, vertexWeights, vertices); +} + + +Value* getSkinWeightsIO(Value** args) +{ + type_check(args[0], MAXNode, _T("getSkinWeights")); + one_typed_value_local(Array* skinData); + vl.skinData = new Array(2); + vl.skinData->size = 2; + getSkinWeightsFn(((MAXNode*)args[0])->to_node(), *vl.skinData); + return_value(vl.skinData); +} + +Value* getSkinWeightsIO(Value** args, int a) +{ + type_check(args[0], MAXNode, _T("getSkinWeights")); + return getSkinWeightsFn(((MAXNode*)args[0])->to_node()); +} + +Value* setSkinWeightsIO(Value** args) +{ + type_check(args[0], MAXNode, _T("setSkinWeights")); + type_check(args[1], Array, _T("setSkinWeights")); + type_check(args[2], Array, _T("setSkinWeights")); + type_check(args[3], Array, _T("setSkinWeights")); + bool result = setSkinWeightsFn(((MAXNode*)args[0])->to_node(), (Array*)args[1], (Array*)args[2], (Array*)args[3]); + if (result) + { + return &true_value; + } + return &false_value; +} + + +Value* getSkinWeightsMethod_cf(Value** arg_list, int count) +{ + check_arg_count_with_keys(getSkinWeightsMethod, 1, count); + return getSkinWeightsIO(arg_list); +} + +Value* getSkinWeightsMethod2_cf(Value** arg_list, int count) +{ + check_arg_count_with_keys(getSkinWeightsMethod2, 1, count); + return getSkinWeightsIO(arg_list, 0); +} + +Value* getSkinWeightsFunction_cf(Value** arg_list, int count) +{ + check_arg_count_with_keys(getSkinWeightsFunction, 1, count); + return getSkinWeightsIO(arg_list); +} + +def_struct_primitive_debug_ok(getSkinWeightsMethod, SkinPPOps, "GetSkinWeights"); + +def_struct_primitive_debug_ok(getSkinWeightsMethod2, SkinPPOps, "GetSkinWeights2"); + +def_visible_primitive_debug_ok(getSkinWeightsFunction, "SPPGetSkinWeights"); + + +Value* setSkinWeightsMethod_cf(Value** arg_list, int count) +{ + // INode* skinnedNode, Value* boneIDs, Value* vertexWeights, Value* vertices + check_arg_count_with_keys(setSkinWeightsMethod, 4, count); + return setSkinWeightsIO(arg_list); +} + +Value* setSkinWeightsFunction_cf(Value** arg_list, int count) +{ + // INode* skinnedNode, Value* boneIDs, Value* vertexWeights, Value* vertices + check_arg_count_with_keys(setSkinWeightsFunction, 4, count); + return setSkinWeightsIO(arg_list); +} + +def_struct_primitive(setSkinWeightsMethod, SkinPPOps, "SetSkinWeights"); + +def_visible_primitive(setSkinWeightsFunction, "SPPSetSkinWeights"); + + +struct SkinPlusPlusFunctionPublish : public FPStaticInterface +{ + DECLARE_DESCRIPTOR(SkinPlusPlusFunctionPublish); + + enum FunctionIDs + { + ID_GetSkinWeights, + ID_SetVertexWeights, + ID_SetSkinWeights, + ID_ReplaceBoneWeights, + }; + BEGIN_FUNCTION_MAP + FN_1(ID_GetSkinWeights, TYPE_VALUE, Fn_GetSkinWeights, TYPE_INODE); + FN_3(ID_SetVertexWeights, TYPE_BOOL, Fn_SetVertexWeights, TYPE_INODE, TYPE_INT, TYPE_VALUE); + FN_4(ID_SetSkinWeights, TYPE_BOOL, Fn_SetSkinWeights, TYPE_INODE, TYPE_VALUE, TYPE_VALUE, TYPE_VALUE); + //FN_4(ID_SetVertexWeights, TYPE_VALUE, Fn_SetVertexWeights, TYPE_VALUE, TYPE_VALUE, TYPE_VALUE, TYPE_VALUE); + //FN_4(ID_ReplaceBoneWeights, TYPE_VALUE, Fn_ReplaceBoneWeights, TYPE_INODE, TYPE_INODE, TYPE_INODE, TYPE_VALUE); + END_FUNCTION_MAP + + const Array* Fn_GetSkinWeights(INode* skinnedNode) + { + one_typed_value_local(Array* skinData); + vl.skinData = new Array(2); + vl.skinData->size = 2; + getSkinWeightsFn(skinnedNode, *vl.skinData); + return_value(vl.skinData); + } + + const BOOL Fn_SetVertexWeights(INode* skinnedNode, int vertexIndex, Value* weightData) + { + Array* _weightData = (Array*)weightData; + return setVertexWeights(skinnedNode, vertexIndex, _weightData); + } + + const BOOL Fn_SetSkinWeights(INode* skinnedNode, Value* boneIDs, Value* vertexWeights, Value* vertices) + { + type_check(boneIDs, Array, _T("SetSkinWeights")); + type_check(vertexWeights, Array, _T("SetSkinWeights")); + Array* vertices_ = NULL; + if (vertices && vertices != &undefined) + { + type_check(vertices, Array, _T("SetSkinWeights")); + vertices_ = (Array*)vertices; + } + return setSkinWeightsFn(skinnedNode, (Array*)boneIDs, (Array*)vertexWeights, vertices_); + } + + + //const Value* Fn_ReplaceBoneWeights( + // INode* skinnedNode, + // INode* oldBone, + // INode* newBone, + // Value* verticesArray = &undefined + //) + //{ + // SkinData* skinData = new SkinData(skinnedNode); + // Array* verticesArray_ = NULL; + // if (verticesArray && verticesArray != &undefined) + // { + // type_check(verticesArray, Array, _T("ReplaceBoneWeights")); + // verticesArray_ = (Array*)verticesArray; + // } + // if (skinData->replaceBoneWeights(oldBone, newBone, verticesArray_)) + // { + // return &true_value; + // } + // return &false_value; + //} + + //const Value* Fn_SetVertexWeights( + // Value* skinnedNode, + // Value* vertexBoneIDsArray, + // Value* vertexWeightsArray, + // Value* verticesArray = &undefined + //) + //{ + // type_check(skinnedNode, MAXNode, _T("SetVertexWeight")); + // type_check(vertexBoneIDsArray, Array, _T("SetVertexWeight")); + // type_check(vertexWeightsArray, Array, _T("SetVertexWeight")); + // Array* verticesArray_ = NULL; + // if (verticesArray != &undefined) + // { + // verticesArray_ = (Array*)verticesArray; + // } + // if (setVertexWeights(skinnedNode->to_node(), (Array*)vertexBoneIDsArray, (Array*)vertexWeightsArray)) + // { + // return &true_value; + // } + // return &false_value; + //} + +}; + + +static SkinPlusPlusFunctionPublish skinPlusPlusFunctionPublish +( + Interface_ID(0x231958ad, 0x1ea823e8), + _T("SkinPP"), + -1, + 0, + FP_CORE, + SkinPlusPlusFunctionPublish::ID_GetSkinWeights, _T("GetSkinWeights"), 0, TYPE_VALUE, 0, 1, + _T("skinnedNode"), 0, TYPE_INODE, + SkinPlusPlusFunctionPublish::ID_SetVertexWeights, _T("SetVertexWeights"), 0, TYPE_VALUE, 0, 3, + _T("skinnedNode"), 0, TYPE_INODE, + _T("vertexIndex"), 0, TYPE_INT, + _T("weightData"), 0, TYPE_VALUE, + SkinPlusPlusFunctionPublish::ID_SetSkinWeights, _T("SetSkinWeights"), 0, TYPE_VALUE, 0, 4, + _T("skinnedNode"), 0, TYPE_INODE, + _T("vertBoneIDsArray"), 0, TYPE_VALUE, + _T("weightsArray"), 0, TYPE_VALUE, + _T("verticesArray"), 0, TYPE_VALUE, f_keyArgDefault, NULL, + //SkinPlusPlusFunctionPublish::ID_ReplaceBoneWeights, _T("ReplaceBoneWeights"), 0, TYPE_VALUE, 0, 4, + //_T("skinnedNode"), 0, TYPE_INODE, + //_T("oldBone"), 0, TYPE_INODE, + //_T("newBone"), 0, TYPE_INODE, + //_T("vertexIDs"), 0, TYPE_VALUE, f_keyArgDefault, NULL, + p_end +); + diff --git a/3DsMax/Skin++.def b/SkinPlusPlus.def similarity index 91% rename from 3DsMax/Skin++.def rename to SkinPlusPlus.def index 3874b78..38e3f48 100644 --- a/3DsMax/Skin++.def +++ b/SkinPlusPlus.def @@ -1,4 +1,4 @@ -LIBRARY Skin++.gup +LIBRARY SkinPlusPlus.gup EXPORTS LibDescription @1 PRIVATE LibNumberClasses @2 PRIVATE diff --git a/SkinPlusPlus.h b/SkinPlusPlus.h new file mode 100644 index 0000000..f0e66dd --- /dev/null +++ b/SkinPlusPlus.h @@ -0,0 +1,103 @@ +#pragma once + + +#include "3dsmaxsdk_preinclude.h" +#include "resource.h" +#include +#include +#include +#include +#include +#include "modstack.h" +//#include "modifiers/bonesdef/BONESDEF.H" +#include +#include +#include +#include "maxscript/macros/define_external_functions.h" +#include +#include + + +extern TCHAR *GetString(int id); + +extern HINSTANCE hInstance; + +// A struct containing weight data of a single skinned vertex. +struct VertexData +{ +private: + Tab bones; + Tab weights; + +public: + VertexData(int size) { this->initialiseVariables(size); }; + VertexData(int vertexID, Array* boneIDs, Array* weights, Tab skinBones); + void initialiseVariables(int size); + void appendVariables(INode* bone, float weight); + Tab getBones() { return this->bones; }; + Tab getWeights() { return this->weights; }; +}; + + //A struct containing weight data of all skinned vertices. +struct VertexDataCollection +{ +public: + Array* weights; + Array* boneIDs; + + VertexDataCollection() {}; + VertexDataCollection(int vertexCount) + { + this->weights = new Array(vertexCount); + this->boneIDs = new Array(vertexCount); + }; +}; + +class SkinData +{ +protected: + // Properties: + bool isValid = false; + INode* node; + IDerivedObject* iDerivedObject; + Modifier* skinModifier; + ISkin* iSkin; + ISkinContextData* iSkinContextData; // used to query skin data + ISkinImportData* iSkinImportData; // used to modify skin data + Tab allVertexData; + Tab cachedUndoVertexData; + +public: + SkinData() {}; + SkinData(INode* skinnedNode) { this->isValid = this->initialise(skinnedNode); } + ~SkinData() + { + this->allVertexData.~Tab(); + this->cachedUndoVertexData.~Tab(); + } + bool initialise(INode* skinnedNode); + Tab getAllVertexData() { return this->allVertexData; }; + Tab getCachedVertexData() { return this->cachedUndoVertexData; }; + virtual void getSkinWeights(Array& ioSkinData); + virtual Array* getSkinWeights(); + bool setSkinWeights(Array* boneIDs, Array* vertexWeights, Array* vertices = NULL); + bool setVertexWeights(int vertexIndex, Array* vertexBones, Array* vertexWeights); + bool setVertexWeights(const int vertexIndex, Array* inBoneIDs, Array* inVertexWeights, Tab inSkinBones); +}; + + +//class SkinDataRestorObject : public RestoreObj { +//private: +// static SkinData* skinData; +//public: +// BOOL updateView; +// +// SkinDataRestorObject(SkinData* inSkinData, BOOL updateView = TRUE); +// ~SkinDataRestorObject(); +// void Restore(int isUndo); +// void Redo(); +// void EndHold(); +// TSTR Description(); +//}; + + diff --git a/3DsMax/Skin++.rc b/SkinPlusPlus.rc similarity index 54% rename from 3DsMax/Skin++.rc rename to SkinPlusPlus.rc index ca03524..321111d 100644 --- a/3DsMax/Skin++.rc +++ b/SkinPlusPlus.rc @@ -19,43 +19,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_PANEL DIALOGEX 0, 0, 108, 156 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_TOOLWINDOW -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - CTEXT "Generated by Autodesk 3ds Max SDK plugin wizard",IDC_STATIC,7,7,94,36 - CONTROL "",IDC_EDIT,"CustEdit",WS_TABSTOP,29,114,35,10 - CONTROL "",IDC_SPIN,"SpinnerControl",0x0,65,114,7,10 - LTEXT "Spinner Cust Control:",IDC_STATIC,20,102,67,8 - CTEXT "TODO: Place panel controls here.",IDC_STATIC,15,63,78,19 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_PANEL, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 101 - TOPMARGIN, 7 - BOTTOMMARGIN, 149 - END -END -#endif // APSTUDIO_INVOKED - - #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // @@ -83,9 +46,9 @@ END STRINGTABLE BEGIN - IDS_LIBDESCRIPTION "Advanced skin processing functionality" + IDS_LIBDESCRIPTION "Plugin for better skin modifier access" IDS_CATEGORY "SkinPlusPlus" - IDS_CLASS_NAME "SkinPlusPlusUtilities" + IDS_CLASS_NAME "SkinPlusPlus" IDS_PARAMS "Parameters" IDS_SPIN "Spin" END @@ -94,30 +57,30 @@ END ///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// English (United Kingdom) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -#pragma code_page(1252) - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +//// English (United Kingdom) resources // -// TEXTINCLUDE +//#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +//LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +//#pragma code_page(1252) +// +//#ifdef APSTUDIO_INVOKED +/////////////////////////////////////////////////////////////////////////////// +//// +//// TEXTINCLUDE +//// +// +//3 TEXTINCLUDE +//BEGIN +// "\r\n" +// "\0" +//END +// +//#endif // APSTUDIO_INVOKED +// +//#endif // English (United Kingdom) resources +/////////////////////////////////////////////////////////////////////////////// // - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // English (United Kingdom) resources -///////////////////////////////////////////////////////////////////////////// - #ifndef APSTUDIO_INVOKED diff --git a/3DsMax/Skin++.sln b/SkinPlusPlus.sln similarity index 64% rename from 3DsMax/Skin++.sln rename to SkinPlusPlus.sln index be9641a..0ef3998 100644 --- a/3DsMax/Skin++.sln +++ b/SkinPlusPlus.sln @@ -1,21 +1,27 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 -VisualStudioVersion = 16.0.30907.101 +VisualStudioVersion = 16.0.31424.327 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Skin++", "Skin++.vcxproj", "{6671F0BA-6FB8-4F35-8392-0676D05113A8}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SkinPlusPlus", "SkinPlusPlus.vcxproj", "{6671F0BA-6FB8-4F35-8392-0676D05113A8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 + Hybrid|Any CPU = Hybrid|Any CPU Hybrid|x64 = Hybrid|x64 + Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6671F0BA-6FB8-4F35-8392-0676D05113A8}.Debug|Any CPU.ActiveCfg = Debug|x64 {6671F0BA-6FB8-4F35-8392-0676D05113A8}.Debug|x64.ActiveCfg = Debug|x64 {6671F0BA-6FB8-4F35-8392-0676D05113A8}.Debug|x64.Build.0 = Debug|x64 + {6671F0BA-6FB8-4F35-8392-0676D05113A8}.Hybrid|Any CPU.ActiveCfg = Hybrid|x64 {6671F0BA-6FB8-4F35-8392-0676D05113A8}.Hybrid|x64.ActiveCfg = Hybrid|x64 {6671F0BA-6FB8-4F35-8392-0676D05113A8}.Hybrid|x64.Build.0 = Hybrid|x64 + {6671F0BA-6FB8-4F35-8392-0676D05113A8}.Release|Any CPU.ActiveCfg = Release|x64 {6671F0BA-6FB8-4F35-8392-0676D05113A8}.Release|x64.ActiveCfg = Release|x64 {6671F0BA-6FB8-4F35-8392-0676D05113A8}.Release|x64.Build.0 = Release|x64 EndGlobalSection @@ -23,6 +29,6 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {1B1E1F57-7549-45BD-8326-1F59F39DF58B} + SolutionGuid = {47597C01-A06B-487C-BB0B-CA7579DDA704} EndGlobalSection EndGlobal diff --git a/3DsMax/Skin++.vcxproj b/SkinPlusPlus.vcxproj similarity index 61% rename from 3DsMax/Skin++.vcxproj rename to SkinPlusPlus.vcxproj index ec497ef..7b7ea40 100644 --- a/3DsMax/Skin++.vcxproj +++ b/SkinPlusPlus.vcxproj @@ -15,11 +15,10 @@ - Skin++ + SkinPlusPlus {6671F0BA-6FB8-4f35-8392-0676D05113A8} DynamicLibrary - $(ADSK_3DSMAX_SDK_2021) - 10.0.17134.0 + $(ADSK_3DSMAX_SDK_2022) @@ -29,41 +28,46 @@ <_ProjectFileVersion>10.0.30319.1 - $(ProjectDir)\output\$(Configuration)\ + $(ADSK_3DSMAX_x64_2022)\Plugins\ $(ProjectDir)\obj\$(Platform)\$(Configuration)\ - Skin++ + SkinPlusPlus .gup - - false - - false + + _USRDLL;%(PreprocessorDefinitions) - $(MaxSdkInc);%(AdditionalIncludeDirectories) + $(MaxSdkInc);C:\Program Files\Python37\include;$(ProjectDir)venv\venv37\Lib\site-packages\pybind11\include;%(AdditionalIncludeDirectories) Level4 + stdcpp14 + + + false - $(MaxSdkLib);%(AdditionalLibraryDirectories) + $(MaxSdkLib);C:\Program Files\Python37\libs;%(AdditionalLibraryDirectories) bmm.lib;core.lib;geom.lib;gfx.lib;mesh.lib;maxutil.lib;maxscrpt.lib;gup.lib;paramblk2.lib;;%(AdditionalDependencies) - Skin++.def + SkinPlusPlus.def - + + + - + - + + - + \ No newline at end of file diff --git a/3DsMax/Skin++.vcxproj.filters b/SkinPlusPlus.vcxproj.filters similarity index 74% rename from 3DsMax/Skin++.vcxproj.filters rename to SkinPlusPlus.vcxproj.filters index 0784e45..fc52329 100644 --- a/3DsMax/Skin++.vcxproj.filters +++ b/SkinPlusPlus.vcxproj.filters @@ -15,15 +15,21 @@ - + Source Files Source Files + + Source Files + + + Source Files + - + Source Files @@ -31,16 +37,19 @@ Header Files - + Header Files Header Files + + Header Files + - + Resource Files - + \ No newline at end of file diff --git a/SkinPlusPlusPy.cpp b/SkinPlusPlusPy.cpp new file mode 100644 index 0000000..23fc6f3 --- /dev/null +++ b/SkinPlusPlusPy.cpp @@ -0,0 +1,61 @@ +#pragma once + +#include "SkinPlusPlusPy.h" + + +//py::array_t> SkinDataPy::getSkinWeights() +py::array_t SkinDataPy::getSkinWeights() +{ + //int vertexCount = this->iSkinContextData->GetNumPoints(); + //weights = new Array(vertexCount); + //boneIDs = new Array(vertexCount); + //weights->size = vertexCount; + //boneIDs->size = vertexCount; + //for (int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) + //{ + // int influenceCount = this->iSkinContextData->GetNumAssignedBones(vertexIndex); + // vl.influenceWeights = new Array(influenceCount); + // vl.influenceBoneIDs = new Array(influenceCount); + // vl.influenceWeights->size = influenceCount; + // vl.influenceBoneIDs->size = influenceCount; + // for (int influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++) + // { + // float infuenceWeight = this->iSkinContextData->GetBoneWeight(vertexIndex, influenceIndex); + // int influenceBoneID = this->iSkinContextData->GetAssignedBone(vertexIndex, influenceIndex) + 1; + // vl.influenceWeights->data[influenceIndex] = Float::intern(infuenceWeight); + // vl.influenceBoneIDs->data[influenceIndex] = Integer::intern(influenceBoneID); + // } + // vl.weights->data[vertexIndex] = vl.influenceWeights; + // vl.boneIDs->data[vertexIndex] = vl.influenceBoneIDs; + //}; + //vl.skinData = new Array(2); + //vl.skinData->size = 2; + //vl.skinData->data[0] = vl.weights; + //vl.skinData->data[1] = vl.boneIDs; + //return_value_tls(vl.weights); + + py::array_t sub_array = py::array_t(10); + //py::array_t> array = py::array_t>(1); + //array[0] = sub_array; + return sub_array; +} + + + +py::array_t getSkinWeights() +{ + SkinDataPy* skinDataPy = new SkinDataPy(); + return skinDataPy->getSkinWeights(); +}; + + + +PYBIND11_MODULE(SkinPlusPlusPy, m) { + m.def("get_skin_weights", &getSkinWeights, "Get Skin Weights"); + +//#ifdef VERSION_INFO +// m.attr("__version__") = VERSION_INFO; +//#else +// m.attr("__version__") = "dev"; +//#endif +} \ No newline at end of file diff --git a/SkinPlusPlusPy.h b/SkinPlusPlusPy.h new file mode 100644 index 0000000..0613b24 --- /dev/null +++ b/SkinPlusPlusPy.h @@ -0,0 +1,20 @@ +#pragma once +#include +#include +#include "SkinPlusPlus.h" + + +namespace py = pybind11; + + +class SkinDataPy: SkinData +{ +//private: + +public: + SkinDataPy() {}; + py::array_t getSkinWeights(); +}; + +py::array_t getSkinWeights(); + diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..61c68c9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel", "pybind11"] +build-backend = "setuptools.build_meta" \ No newline at end of file diff --git a/3DsMax/resource.h b/resource.h similarity index 75% rename from 3DsMax/resource.h rename to resource.h index 832ba12..2f454d5 100644 --- a/3DsMax/resource.h +++ b/resource.h @@ -1,28 +1,15 @@ //{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by Skin++.rc +// Microsoft Visual C++ generated include file. +// Used by SkinPlusPlus.rc // - - #define IDS_LIBDESCRIPTION 1 #define IDS_CATEGORY 2 #define IDS_CLASS_NAME 3 #define IDS_PARAMS 4 #define IDS_SPIN 5 - - - - - - - -#define IDD_PANEL 101 - #define IDC_CLOSEBUTTON 1000 #define IDC_DOSTUFF 1000 #define IDC_COLOR 1456 -#define IDC_EDIT 1490 -#define IDC_SPIN 1496 // Next default values for new objects // diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..4487dc3 --- /dev/null +++ b/setup.py @@ -0,0 +1,19 @@ +from setuptools import setup, Extension +import pybind11 + +cpp_args = ["-std=c++14", "-stdlib=libc++", "-mmacosx-version-min=10.7"] + +skin_plus_plus_module = Extension( + "SkinPlusPlusPy", + sources=["SkinPlusPlusPy.cpp"], + include_dirs=[pybind11.get_include()], + language="c++", + extra_compile_args=cpp_args, + ) + +setup( + name="SkinPlusPlusPy", + version="1.0", + description="Python package for getting and setting skin weights in 3DsMax", + ext_modules=[skin_plus_plus_module], +) \ No newline at end of file diff --git a/temp.cpp b/temp.cpp new file mode 100644 index 0000000..03fa36a --- /dev/null +++ b/temp.cpp @@ -0,0 +1,575 @@ +//#include "SkinPlusPlus.h" +// +//bool VertexData::appendBone(INode* inBone) +//{ +// return this->bones.Append(1, &inBone, 1); +//} +// +//bool VertexData::appendBoneID(Integer inBoneID) +//{ +// return this->boneIDs.Append(1, &inBoneID, 1); +//} +// +//bool VertexData::appendWeight(float inWeight) +//{ +// return this->weights.Append(1, &inWeight, 1); +//} +// +// +//SkinData::SkinData(INode* skinnedNode) { this->isValid = this->initialise(skinnedNode); } +// +//SkinData::~SkinData() +//{ +// this->allVertexData.~Tab(); +// this->cachedVertexData.~Tab(); +//} +// +//INode* SkinData::getNode() +//{ +// return this->node; +//} +// +//bool SkinData::setData(INode* skinnedNode) +//{ +// this->allVertexData = Tab(); +// this->node = skinnedNode; +// Object* object = this->node->GetObjectRef(); +// if (!object || (object->SuperClassID() != GEN_DERIVOB_CLASS_ID)) +// { +// return false; +// } +// this->derivedObject = (IDerivedObject*)(object); +// +// for (int modifierIndex = 0; modifierIndex < this->derivedObject->NumModifiers(); modifierIndex++) +// { +// this->modifier = this->derivedObject->GetModifier(modifierIndex); +// +// if (this->modifier->ClassID() != SKIN_CLASSID) +// { +// continue; +// } +// this->skin = (ISkin*)this->modifier->GetInterface(I_SKIN); +// +// if (!this->skin) +// { +// continue; +// } +// this->skinImportData = (ISkinImportData*)this->modifier->GetInterface(I_SKINIMPORTDATA); +// +// if (!this->skinImportData) +// { +// continue; +// } +// this->skinContextData = this->skin->GetContextInterface(skinnedNode); +// +// if (!this->skinContextData) +// { +// continue; +// } +// this->boneModData = (BoneModData*)this->derivedObject->GetModContext(modifierIndex)->localData; +// +// this->bonesDefMod = (BonesDefMod*)this->modifier; +// +// return true; +// } +// return false; +//} +// +//void SkinData::cacheVertexDataForUndo() +//{ +// //theHold.Begin(); +// //if (theHold.Holding()) +// //{ +// // theHold.Put(new SkinDataRestorObject(this)); +// // theHold.Accept(_T("Caching Vertex Weights")); +// //} +// return; +//} +// +//VertexData* SkinData::setCachedVertexDataIO(const int inVertexIndex, Tab inSkinBones) +//{ +// const int influenceCount = this->skinContextData->GetNumAssignedBones(inVertexIndex); +// VertexData* vertexData = new VertexData(inVertexIndex); +// for (int influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++) +// { +// const float vertexBoneWeight = this->skinContextData->GetBoneWeight(inVertexIndex, influenceIndex); +// if (vertexBoneWeight < 0.00001f) +// { +// continue; +// } +// vertexData->appendWeight(vertexBoneWeight); +// const int skinBoneIndex = this->skinContextData->GetAssignedBone(inVertexIndex, influenceIndex); +// INode* skinBone = inSkinBones[skinBoneIndex]; +// vertexData->appendBone(skinBone); +// } +// return vertexData; +//} +// +//Tab SkinData::setCachedVertexData() +//{ +// int vertexCount = this->skinContextData->GetNumPoints(); +// this->cachedVertexData = Tab(); +// Tab skinBones; +// int skinBonesCount = this->skin->GetNumBones(); +// for (int boneIndex = 0; boneIndex < skinBonesCount; boneIndex++) +// { +// INode* bone = this->skin->GetBone(boneIndex); +// skinBones.Append(1, &bone, 1); +// } +// for (int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) +// { +// VertexData* vertexData = this->setCachedVertexDataIO(vertexIndex, skinBones); +// this->cachedVertexData.Append(1, &vertexData, 1); +// } +// return this->cachedVertexData; +//} +// +//bool SkinData::setVertexDataFromCacheIO(VertexData* inVertexData) +//{ +// int id = inVertexData->getID(); +// Tab bones = inVertexData->getBones(); +// Tab weights = inVertexData->getWeights(); +// BOOL result = this->skinImportData->AddWeights(this->node, id, bones, weights); +// if (result) return true; else return false; +//} +// +//bool SkinData::setVertexDataFromCache(Tab inVertexDataTab) +//{ +// const int inVertexDataCount = inVertexDataTab.Count(); +// const int skinVertexCount = this->skinContextData->GetNumPoints(); +// if (inVertexDataCount != skinVertexCount) +// { +// throw RuntimeError(GetString(IDS_PW_EXCEEDED_BONE_COUNT), (Value*)this->node); +// } +// for (int vertexIndex = 0; vertexIndex < skinVertexCount; vertexIndex++) +// { +// VertexData* vertexData = inVertexDataTab[vertexIndex]; +// this->setVertexDataFromCacheIO(vertexData); +// } +// this->modifier->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE); +// //GetCOREInterface()->RedrawViews(GetCOREInterface()->GetTime()); +// return true; +//} +// +//bool SkinData::setVertexDataIO(const int vertexIndex, Array* boneIDs, Array* vertexWeights, Tab skinBones) +//{ +// Array* vertexBoneIDs = (Array*)boneIDs->data[vertexIndex]; +// Array* vertexBoneWeights = (Array*)vertexWeights->data[vertexIndex]; +// VertexData* vertexData = new VertexData(vertexIndex); +// for (int vertexBoneIndex = 0; vertexBoneIndex < vertexBoneIDs->size; vertexBoneIndex++) +// { +// float weight = vertexBoneWeights->data[vertexBoneIndex]->to_float(); +// if (weight < 0.0f) weight = 0.0f; +// if (weight > 1.0f) weight = 1.0f; +// const int vertexBoneID = vertexBoneIDs->data[vertexBoneIndex]->to_int(); +// INode* vertexBoneIDNode = skinBones[vertexBoneID - 1]; +// vertexData->appendBone(vertexBoneIDNode); +// vertexData->appendWeight(weight); +// } +// this->allVertexData.Append(1, &vertexData, 1); +// BOOL result = this->skinImportData->AddWeights(this->node, vertexIndex, vertexData->getBones(), vertexData->getWeights()); +// if (result) return true; else return false; +//} +// +//bool SkinData::setAllVertexWeights(Array* boneIDs, Array* vertexWeights, Array* vertices) +//{ +// this->cacheVertexDataForUndo(); +// const int bonesArraySize = boneIDs->size; +// const int weightsArraySize = vertexWeights->size; +// if (bonesArraySize != weightsArraySize) +// { +// throw RuntimeError(GetString(IDS_PW_WEIGHT_BONE_COUNT), (Value*)this->node); +// } +// Tab skinBones; +// int skinBonesCount = this->skin->GetNumBones(); +// for (int boneIndex = 0; boneIndex < skinBonesCount; boneIndex++) +// { +// INode* bone = this->skin->GetBone(boneIndex); +// skinBones.Append(1, &bone, 1); +// } +// bool allVertexWeightsSet = true; +// if (vertices) +// { +// const int inVerticesCount = vertices->size; +// for (int inVerticesIndex = 0; inVerticesIndex < inVerticesCount; inVerticesIndex++) +// { +// const int vertexIndex = vertices->data[inVerticesIndex]->to_int() - 1; +// if (!this->setVertexDataIO(vertexIndex, boneIDs, vertexWeights, skinBones)) +// { +// allVertexWeightsSet = false; +// } +// } +// } +// else +// { +// const int vertexCount = this->skinContextData->GetNumPoints(); +// for (int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) +// { +// if (!this->setVertexDataIO(vertexIndex, boneIDs, vertexWeights, skinBones)) +// { +// allVertexWeightsSet = false; +// } +// } +// } +// +// this->modifier->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE); +// GetCOREInterface()->RedrawViews(GetCOREInterface()->GetTime()); +// return allVertexWeightsSet; +//} +// +//bool SkinData::getVertexDataIO(const int inVertexIndex, VertexDataCollection* ioAllVertexData) +//{ +// const int influenceCount = this->skinContextData->GetNumAssignedBones(inVertexIndex); +// Array* vertexBoneWeights = new Array(influenceCount); +// Array* vertexBoneIDs = new Array(influenceCount); +// for (int influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++) +// { +// const float vertexBoneWeight = this->skinContextData->GetBoneWeight(inVertexIndex, influenceIndex); +// vertexBoneWeights->append(Double::intern(vertexBoneWeight)); +// const int skinBoneIndex = this->skinContextData->GetAssignedBone(inVertexIndex, influenceIndex) + 1; +// vertexBoneIDs->append(Integer::intern(skinBoneIndex)); +// } +// ioAllVertexData->weights->append(vertexBoneWeights); +// ioAllVertexData->boneIDs->append(vertexBoneIDs); +// return true; +//} +// +////BonesDefMod* SkinData::getBonesDefMod() +////{ +//// if (!this->boneDefsMod) +//// { +//// SClass_ID sid = modifier->SuperClassID(); +//// Class_ID id = modifier->ClassID(); +//// if (sid != OSM_CLASS_ID || id != Class_ID(9815843, 87654)) +//// return NULL; +//// } +//// this->boneDefsMod = (BonesDefMod*)modifier; +////} +// +//Array* SkinData::getVertexWeights() +//{ +// //int vertexCount = this->boneModData->VertexData.Count(); +// int vertexCount = this->skinContextData->GetNumPoints(); +// +// Array* outSkinData = new Array(2); +// Array* weights = new Array(vertexCount); +// Array* boneIDs = new Array(vertexCount); +// outSkinData->data[0] = weights; +// outSkinData->data[1] = boneIDs; +// +// //the_listener->edit_stream->printf(_T("vertexCount: %d\n"), vertexCount); +// for (int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) +// { +// //this->bonesDefMod->GetNumBones(); +// const int influenceCount = this->skinContextData->GetNumAssignedBones(vertexIndex); +// //const int influenceCount = this->boneModData->VertexData[vertexIndex]->WeightCount(); +// Array* influenceWeights = new Array(influenceCount); +// Array* influenceBoneIDs = new Array(influenceCount); +// for (int influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++) +// { +// const float infuenceWeight = this->skinContextData->GetBoneWeight(vertexIndex, influenceIndex); +// //const float infuenceWeight = this->bonesDefMod->RetrieveNormalizedWeight( +// // this->boneModData, +// // vertexIndex, +// // influenceIndex +// //); +// +// //the_listener->edit_stream->printf(_T("Weight: %d\n"), infuenceWeight); +// influenceWeights->append(Double::intern(infuenceWeight)); +// const int influenceBoneID = this->skinContextData->GetAssignedBone(vertexIndex, influenceIndex) + 1; +// influenceBoneIDs->append(Integer::intern(influenceBoneID)); +// //the_listener->edit_stream->printf(_T("ID: %d\n"), influenceBoneID); +// //the_listener->edit_stream->printf(_T("----------")); +// } +// weights->append(influenceWeights); +// boneIDs->append(influenceBoneIDs); +// } +// outSkinData->data[0] = weights; +// outSkinData->data[1] = boneIDs; +// +// return outSkinData; +//} +// +//bool SkinData::getVertexWeights(int inVertexIndex, Array* ioWeightData, bool zeroBased) +//{ +// int vertexIndex = inVertexIndex; +// if (!zeroBased) vertexIndex -= 1; +// const int influenceCount = this->skinContextData->GetNumAssignedBones(vertexIndex); +// Array* vertexWeightData = new Array(influenceCount); +// Array* vertexBoneIDData = new Array(influenceCount); +// for (int influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++) +// { +// const float vertexBoneWeight = this->skinContextData->GetBoneWeight(vertexIndex, influenceIndex); +// vertexWeightData->append(Double::intern(vertexBoneWeight)); +// const int skinBoneIndex = this->skinContextData->GetAssignedBone(vertexIndex, influenceIndex) + 1; +// vertexBoneIDData->append(Integer::intern(skinBoneIndex)); +// } +// ioWeightData->append(vertexWeightData); +// ioWeightData->append(vertexBoneIDData); +// +// return true; +//} +// +//bool SkinData::setVertexWeights(int inVertexIndex, Array* inWeightData) +//{ +// //this->cacheVertexDataForUndo(); +// Array* vertexBoneWeights = (Array*)inWeightData->data[0]; +// Array* vertexBones = (Array*)inWeightData->data[1]; +// VertexData* vertexData = new VertexData(inVertexIndex); +// for (int vertexBoneIndex = 0; vertexBoneIndex < vertexBoneWeights->size; vertexBoneIndex++) +// { +// float weight = vertexBoneWeights->data[vertexBoneIndex]->to_float(); +// if (weight < 0.0f) weight = 0.0f; +// if (weight > 1.0f) weight = 1.0f; +// MAXNode* mxsVertexBoneIDNode = (MAXNode*)vertexBones->data[vertexBoneIndex]; +// vertexData->appendBone(mxsVertexBoneIDNode->to_node()); +// vertexData->appendWeight(weight); +// } +// this->allVertexData.Append(1, &vertexData, 1); +// BOOL result = this->skinImportData->AddWeights( +// this->node, +// inVertexIndex, +// vertexData->getBones(), +// vertexData->getWeights() +// ); +// +// this->modifier->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE); +// GetCOREInterface()->RedrawViews(GetCOREInterface()->GetTime()); +// +// if (result) return true; else return false; +//} +// +//int SkinData::getBoneID(INode* inBone, bool zeroBased) +//{ +// const int boneCount = this->skin->GetNumBones(); +// for (int boneID = 0; boneID < boneCount; boneID++) +// { +// INode* bone = this->skin->GetBone(boneID); +// if (bone == inBone) +// { +// if (zeroBased) +// { +// return boneID; +// } +// return boneID + 1; +// } +// } +// return -1; +//} +// +//bool SkinData::replaceBoneWeightsIO(int vertexIndex, INode* newBone, int oldBoneID, int newBoneID, Tab skinnedBones) +//{ +// int oldBoneIDFound = false; +// bool newBoneIDFound = false; +// float totalVertexBoneWeight = 0.0; +// Tab vertexBonesTab; +// Tab vertexBoneWeightsTab; +// const int influenceCount = this->skinContextData->GetNumAssignedBones(vertexIndex); +// for (int influenceIndex = 0; influenceIndex < influenceCount; influenceIndex++) +// { +// float vertexBoneWeight = this->skinContextData->GetBoneWeight(vertexIndex, influenceIndex); +// const int skinBoneIndex = this->skinContextData->GetAssignedBone(vertexIndex, influenceIndex); +// if (oldBoneID == skinBoneIndex) +// { +// oldBoneIDFound = true; +// totalVertexBoneWeight += vertexBoneWeight; +// } +// else if (newBoneID == skinBoneIndex) +// { +// newBoneIDFound = true; +// totalVertexBoneWeight += vertexBoneWeight; +// } +// else +// { +// INode* bone = skinnedBones[skinBoneIndex]; +// vertexBonesTab.Append(1, &bone, 1); +// vertexBoneWeightsTab.Append(1, &vertexBoneWeight, 1); +// } +// } +// if (totalVertexBoneWeight > 0.0) +// { +// vertexBonesTab.Append(1, &newBone, 1); +// vertexBoneWeightsTab.Append(1, &totalVertexBoneWeight, 1); +// BOOL mxsResult = this->skinImportData->AddWeights(this->node, vertexIndex, vertexBonesTab, vertexBoneWeightsTab); +// if (!mxsResult) +// { +// return false; +// } +// } +// return true; +//} +// +//bool SkinData::replaceBoneWeights(INode* oldBone, INode* newBone, Array* inVertexIDs) +//{ +// +// if (!this->skinContextData) +// { +// return false; +// } +// +// int oldBoneID = this->getBoneID(oldBone, true); +// if (oldBoneID == -1) +// { +// throw RuntimeError(_T("No bone id found,make sure it exists in the skin modifier: "), oldBone->GetName()); +// } +// +// int newBoneID = this->getBoneID(newBone, true); +// if (newBoneID == -1) +// { +// throw RuntimeError(_T("No bone id found, make sure it exists in the skin modifier: "), newBone->GetName()); +// } +// //this->cacheVertexDataForUndo(); +// +// int skinBonesCount = this->skin->GetNumBones(); +// Tab skinBones; +// +// for (int boneIndex = 0; boneIndex < skinBonesCount; boneIndex++) +// { +// INode* bone = this->skin->GetBone(boneIndex); +// skinBones.Append(1, &bone, 1); +// } +// +// bool result = true; +// if (inVertexIDs) +// { +// for (int index = 0; index < inVertexIDs->size; index++) +// { +// int vertexIndex = inVertexIDs->data[index]->to_int() - 1; +// result = this->replaceBoneWeightsIO(vertexIndex, newBone, oldBoneID, newBoneID, skinBones); +// if (!result) +// { +// the_listener->edit_stream->printf(_T("Failed to set weight for vertex: %d\n"), vertexIndex); +// break; +// } +// } +// } +// else +// { +// int vertexCount = this->skinContextData->GetNumPoints(); +// for (int vertexIndex = 0; vertexIndex < vertexCount; vertexIndex++) +// { +// result = this->replaceBoneWeightsIO(vertexIndex, newBone, oldBoneID, newBoneID, skinBones); +// if (!result) +// { +// the_listener->edit_stream->printf(_T("Failed to set weight for vertex: %d\n"), vertexIndex); +// break; +// } +// } +// } +// this->modifier->NotifyDependents(FOREVER, PART_GEOM, REFMSG_CHANGE); +// GetCOREInterface()->RedrawViews(GetCOREInterface()->GetTime()); +// +// return result; +//} +// +// +// +//Array* getVertexWeights(INode* node) +//{ +// SkinData* skinData = new SkinData(node); +// return skinData->getVertexWeights(); +//} +// +//bool setVertexWeights(INode* node, Array* boneIDs, Array* weights) +//{ +// SkinData* skinData = new SkinData(node); +// return skinData->setAllVertexWeights(boneIDs, weights); +//} +// +// +// +//static Modifier* getSkinModifier(INode* node) +//{ +// Object* obj = node->GetObjectRef(); +// if (!obj || (obj->SuperClassID() != GEN_DERIVOB_CLASS_ID)) +// { +// return NULL; +// } +// +// IDerivedObject* derivedObject = (IDerivedObject*)(obj); +// for (int modifierIndex = 0; modifierIndex < derivedObject->NumModifiers(); modifierIndex++) +// { +// Modifier* modifier = derivedObject->GetModifier(modifierIndex); +// if (modifier->ClassID() != SKIN_CLASSID) +// { +// continue; +// } +// +// if ((ISkin*)modifier->GetInterface(I_SKIN)) +// { +// return modifier; +// } +// } +// return NULL; +//} +// +//static ISkinContextData* getSkinContextData(INode* inSkinnedNode) +//{ +// Object* obj = inSkinnedNode->GetObjectRef(); +// +// if (!obj || (obj->SuperClassID() != GEN_DERIVOB_CLASS_ID)) +// { +// return NULL; +// } +// +// IDerivedObject* derObj = (IDerivedObject*)(obj); +// +// for (int modifierIndex = 0; modifierIndex < derObj->NumModifiers(); modifierIndex++) +// { +// Modifier* modifier = derObj->GetModifier(modifierIndex); +// if (modifier->ClassID() != SKIN_CLASSID) +// { +// continue; +// } +// +// ISkin* skin = (ISkin*)modifier->GetInterface(I_SKIN); +// +// if (skin == NULL) +// { +// continue; +// } +// +// ISkinContextData* skinContextData = skin->GetContextInterface(inSkinnedNode); +// if (!skinContextData) +// { +// return NULL; +// } +// +// return skinContextData; +// } +// +// return NULL; +//} +// +//static ISkinImportData* getSkinImportData(INode* inSkinnedNode) +//{ +// Object* obj = inSkinnedNode->GetObjectRef(); +// +// if (!obj || (obj->SuperClassID() != GEN_DERIVOB_CLASS_ID)) +// { +// return NULL; +// } +// +// IDerivedObject* derObj = (IDerivedObject*)(obj); +// +// for (int modifierIndex = 0; modifierIndex < derObj->NumModifiers(); modifierIndex++) +// { +// Modifier* modifier = derObj->GetModifier(modifierIndex); +// +// if (modifier->ClassID() != SKIN_CLASSID) +// { +// continue; +// } +// +// ISkinImportData* skinImportData = (ISkinImportData*)modifier->GetInterface(I_SKINIMPORTDATA); +// +// if (skinImportData == NULL) +// { +// continue; +// } +// +// return skinImportData; +// } +// +// return NULL; +//} diff --git a/test/test.ms b/test/test.ms new file mode 100644 index 0000000..8eda060 --- /dev/null +++ b/test/test.ms @@ -0,0 +1,162 @@ +pyTime = python.import "time" + +fn mxsGetSkinWeights node = ( + skops = SkinOps() + skopGetVertexWeight = skops.GetVertexWeight + skopGetVertexWeightCount = skops.GetVertexWeightCount + skopGetVertexWeightBoneID = skops.GetVertexWeightBoneID + -- skopReplaceVertexWeights = skops.ReplaceVertexWeights + -- skinOps.ReplaceVertexWeights \ ( | ) \ + -- ( | ) [(node: | name:)] + skinModifier = node.Modifiers[Skin] + vertexCount = skops.GetNumberVertices(skinModifier) + skinWeights = #() + skinBoneIDs = #() + for vertexIndex = 1 to vertexCount do + ( + influenceCount = skopGetVertexWeightCount skinModifier vertexIndex + vertexWeights = for influenceIndex = 1 to influenceCount collect skopGetVertexWeight skinModifier vertexIndex influenceIndex + vertexBoneIDs = for influenceIndex = 1 to influenceCount collect skopGetVertexWeightBoneID skinModifier vertexIndex influenceIndex + Append skinWeights vertexWeights + Append skinBoneIDs vertexBoneIDs + ) + + #(skinWeights, skinBoneIDs) +) + +fn mxsSetSkinWeights node boneIDs weights = ( + skops = SkinOps() + skopGetVertexWeight = skops.GetVertexWeight + skopGetVertexWeightCount = skops.GetVertexWeightCount + skopGetVertexWeightBoneID = skops.GetVertexWeightBoneID + skopReplaceVertexWeights = skops.ReplaceVertexWeights + -- skinOps.ReplaceVertexWeights \ ( | ) \ + -- ( | ) [(node: | name:)] + skinModifier = node.Modifiers[Skin] + vertexCount = skops.GetNumberVertices(skinModifier) + for vertexIndex = 1 to vertexCount do + ( + skopReplaceVertexWeights skinModifier vertexIndex boneIDs[vertexIndex] weights[vertexIndex] + ) +) + + +fn mxs_GetSkinWeights _obj _loopCount = ( + startTime = pyTime.time() + for a = 1 to _loopCount do GetSkinWeights _obj + timeTaken = (pyTime.time() - startTime) + print("mxs: " + (timeTaken as string)) + + timeTaken +) + +fn cppfp_GetSkinWeights _obj _loopCount = ( + SkinPPGetSkinWeights = SkinPP.GetSkinWeights + startTime = pyTime.time() + for a = 1 to _loopCount do SkinPPGetSkinWeights _obj + timeTaken = (pyTime.time() - startTime) + print("c++ function publish: " + (timeTaken as string)) + + timeTaken +) + +fn cpppm_GetSkinWeights _obj _loopCount = ( + SkinPPOpss = SkinPPOps() + SkinPPOpssGetSkinWeights = SkinPPOpss.GetSkinWeights + startTime = pyTime.time() + for a = 1 to _loopCount do SkinPPOpssGetSkinWeights _obj + timeTaken = (pyTime.time() - startTime) + print("c++ primative method: " + (timeTaken as string)) + + timeTaken +) + +fn cpppm2_GetSkinWeights _obj _loopCount = ( + SkinPPOpss = SkinPPOps() + SkinPPOpssGetSkinWeights2 = SkinPPOpss.GetSkinWeights2 + startTime = pyTime.time() + for a = 1 to _loopCount do SkinPPOpssGetSkinWeights2 _obj + timeTaken = (pyTime.time() - startTime) + print("c++ primative method2: " + (timeTaken as string)) + + timeTaken +) + +fn cpppf_GetSkinWeights _obj _loopCount = ( + startTime = pyTime.time() + for a = 1 to _loopCount do SPPGetSkinWeights _obj + timeTaken = (pyTime.time() - startTime) + print("c++ primative function: " + (timeTaken as string)) + + timeTaken +) + + +fn mxs_SetSkinWeights _obj _loopCount _boneIDs _weights = ( + startTime = pyTime.time() + for a = 1 to _loopCount do SetSkinWeights _obj _boneIDs _weights + timeTaken = (pyTime.time() - startTime) + print("mxs taken: " + (timeTaken as string)) + + timeTaken +) + +fn cppfp_SetSkinWeights _obj _loopCount _boneIDs _weights = ( + SkinPPSetSkinWeights = SkinPP.SetSkinWeights + startTime = pyTime.time() + for a = 1 to _loopCount do SkinPPSetSkinWeights _obj _boneIDs _weights + timeTaken = (pyTime.time() - startTime) + print("c++ function publish: " + (timeTaken as string)) + + timeTaken +) + +fn cpppm_SetSkinWeights _obj _loopCount _boneIDs _weights = ( + SkinPPOpss = SkinPPOps() + SkinPPOpssSetSkinWeights = SkinPPOpss.SetSkinWeights + startTime = pyTime.time() + for a = 1 to _loopCount do SkinPPOpssSetSkinWeights _obj _boneIDs _weights #() + timeTaken = (pyTime.time() - startTime) + print("c++ primative method: " + (timeTaken as string)) + + timeTaken +) + +fn cpppf_SetSkinWeights _obj _loopCount _boneIDs _weights = ( + startTime = pyTime.time() + for a = 1 to _loopCount do SPPSetSkinWeights _obj _boneIDs _weights #() + timeTaken = (pyTime.time() - startTime) + print("c++ primative function: " + (timeTaken as string)) + + timeTaken +) + +if False do +( + obj = $Sphere002 + loopCount = 1 + + getFunctions = #( + mxs_GetSkinWeights, + cppfp_GetSkinWeights, + cpppm_GetSkinWeights, + cpppm2_GetSkinWeights, + cpppf_GetSkinWeights + ) + + fn comparePerformance functs = ( + times = for funct in functs collect ( + funct obj loopCount + ) + maxTime = amax times + print(maxTime) + + for t in times collect ( format maxTime / t ) + ) +) +-- comparePerformance getFunctions + + +-- weights = for a = 1 to obj.Verts.Count collect #(0.5, 0.5) +-- ids = for a = 1 to obj.Verts.Count collect #(1, 2) +-- "---" \ No newline at end of file diff --git a/test/test.py b/test/test.py new file mode 100644 index 0000000..4ee3658 --- /dev/null +++ b/test/test.py @@ -0,0 +1,226 @@ +from __future__ import annotations + +import functools +import pathlib +import time + +from pymxs import runtime as mxRt +from typing import Any +from typing import Callable + +_SKOPS = mxRt.SkinOps() +GetVertexWeight = _SKOPS.GetVertexWeight +GetVertexWeightCount = _SKOPS.GetVertexWeightCount +GetVertexWeightBoneID = _SKOPS.GetVertexWeightBoneID +ReplaceVertexWeights = _SKOPS.ReplaceVertexWeights + + +_SKINPPOPS = mxRt.SkinPPOps() +SKINPP_GetSkinWeights = mxRt.SkinPP.GetSkinWeights +SKINPPOPS_GetSkinWeights = _SKINPPOPS.GetSkinWeights +SPPGetSkinWeights = mxRt.SPPGetSkinWeights + +SKINPP_SetSkinWeights = mxRt.SkinPP.SetSkinWeights +SKINPPOPS_SetSkinWeights = _SKINPPOPS.SetSkinWeights +SPPSetSkinWeights = mxRt.SPPSetSkinWeights + +import site +site.addsitedir(r"D:\Code\Git\SkinPlusPlus\PyModules\skin_plus_plus\x64\Release") + +import SkinPlusPlusPymxs + +skin_data = SkinPlusPlusPymxs.SkinData() +skin_data.initialise("Sphere001") +skin_weights = skin_data.getSkinWeights() +print(skin_weights[0][1]) + + +__loops__ = 1 +def set_loops(value: int): + global __loops__ + __loops__ = value + +def get_loops(): + global __loops__ + return __loops__ + + +def timer(data_dict: dict[str, tuple[float, Any]]) -> Callable: + def wrapper(function: Callable) -> Callable: + @functools.wraps(function) + def wrapper_timer(*args, **kwargs) -> Any: + start_time = time.perf_counter() + value: Any = None + for _ in range(get_loops()): + value = function(*args, **kwargs) + run_time = time.perf_counter() - start_time + data_dict[f"{function.__name__!r}"] = (run_time, value) + return value + return wrapper_timer + return wrapper + +def getMxsFunctions(): + current_file = pathlib.Path(__file__) + mxRt.FileIn(str(current_file.with_suffix(".ms"))) + return mxRt.mxsGetSkinWeights, mxRt.mxsSetSkinWeights + +mxsGetSkinWeights, mxsSetSkinWeights = getMxsFunctions() + +def GetSkinWeights(node) -> tuple[list[list[float]], list[list[int]]]: + skinModifier = node.Modifiers[mxRt.Skin] + vertexCount = _SKOPS.GetNumberVertices(skinModifier) + skinWeights: list[list[float]] = [] + skinBoneIDs: list[list[int]] = [] + for vertexIndex in range(1, vertexCount + 1): + influenceCount = GetVertexWeightCount(skinModifier, vertexIndex) + vertexWeights:list[float] = [ + GetVertexWeight(skinModifier, vertexIndex, influenceIndex) for influenceIndex in range(1, influenceCount + 1) + ] + vertexBoneIDs: list[int] = [ + GetVertexWeightBoneID(skinModifier, vertexIndex, influenceIndex) for influenceIndex in range(1, influenceCount + 1) + ] + skinWeights.append(vertexWeights) + skinBoneIDs.append(vertexBoneIDs) + + return skinWeights, skinBoneIDs + +def SetSkinWeights(node, boneIDs, weights) -> None: + skinModifier = node.Modifiers[mxRt.Skin] + vertexCount = _SKOPS.GetNumberVertices(skinModifier) + for vertexIndex in range(vertexCount, 1): + ReplaceVertexWeights(skinModifier, vertexIndex, boneIDs[vertexIndex], weights[vertexIndex]) + + +get_timer_dict: dict[str, tuple[float, Any]] = {} +@timer(get_timer_dict) +def mxs_GetSkinWeights(_obj): + data = mxsGetSkinWeights(_obj) + weights = [list(weights) for weights in data[0]] + boneIDs = [list(boneIDs) for boneIDs in data[1]] + + return weights, boneIDs + + +@timer(get_timer_dict) +def pymxs_GetSkinWeights(_obj): + return GetSkinWeights(_obj) + +@timer(get_timer_dict) +def cppfp_GetSkinWeights(_obj): + data = SKINPP_GetSkinWeights(_obj) + weights = [list(weights) for weights in data[0]] + boneIDs = [list(boneIDs) for boneIDs in data[1]] + + return weights, boneIDs + +@timer(get_timer_dict) +def cpppm_GetSkinWeights(_obj): + data = SKINPPOPS_GetSkinWeights(_obj) + weights = [list(weights) for weights in data[0]] + boneIDs = [list(boneIDs) for boneIDs in data[1]] + + return weights, boneIDs + +@timer(get_timer_dict) +def cpppf_GetSkinWeights(_obj): + data = SPPGetSkinWeights(_obj) + + weights = [list(weights) for weights in data[0]] + boneIDs = [list(boneIDs) for boneIDs in data[1]] + + return weights, boneIDs + +@timer(get_timer_dict) +def pybind11_GetSkinWeights(_obj): + + return SkinPlusPlusPymxs.get_skin_weights(_obj.Name) + +@timer(get_timer_dict) +def pybind11np_GetSkinWeights(_obj): + + return SkinPlusPlusPymxs.get_skin_weights_np(_obj.Name) + +@timer(get_timer_dict) +def pybind11npmove_GetSkinWeights(_obj): + + return SkinPlusPlusPymxs.get_skin_weights_np_move(_obj.Name) + +@timer(get_timer_dict) +def pybind11nptakeownership_GetSkinWeights(_obj): + + return SkinPlusPlusPymxs.get_skin_weights_np_take_ownership(_obj.Name) + + +set_timer_dict: dict[str, tuple[float, Any]] = {} +@timer(set_timer_dict) +def mxs_SetSkinWeights( _obj, _boneIDs, _weights): + return SetSkinWeights(_obj, _boneIDs, _weights) + +@timer(set_timer_dict) +def cppfp_SetSkinWeights( _obj, _boneIDs, _weights): + return SKINPP_SetSkinWeights(_obj, _boneIDs, _weights) + +@timer(set_timer_dict) +def cpppm_SetSkinWeights( _obj, _boneIDs, _weights): + return SKINPPOPS_SetSkinWeights(_obj, _boneIDs, _weights, []) + +@timer(set_timer_dict) +def cpppf_SetSkinWeights( _obj, _boneIDs, _weights): + return SPPSetSkinWeights(_obj, _boneIDs, _weights, []) + + +obj = mxRt.GetNodeByName("Sphere001") + +get_function_list = ( + # pymxs_GetSkinWeights, + # mxs_GetSkinWeights, + # cppfp_GetSkinWeights, + # cpppm_GetSkinWeights, + # cpppf_GetSkinWeights, + pybind11_GetSkinWeights, + pybind11np_GetSkinWeights, + pybind11npmove_GetSkinWeights, + pybind11nptakeownership_GetSkinWeights, + # lambda: pybind11np_GetSkinWeights(obj), +) + +# weights = [(0.5, 0.5) for _ in range(obj.Verts.Count)] +# ids = [(1, 2) for _ in range(obj.Verts.Count)] +# set_function_list = ( +# lambda: mxs_SetSkinWeights(obj, weights, ids), +# lambda: cppfp_SetSkinWeights(obj, weights, ids), +# lambda: cpppm_SetSkinWeights(obj, weights, ids), +# lambda: cpppf_SetSkinWeights(obj, weights, ids), +# ) + +set_loops(1) +def run_functions(function_list, _obj): + for function in function_list: + result = function(_obj) + if result is None: + continue + print(type(result)) + print(len(result)) + +def process_results(time_data: dict[str, tuple[float, Any]]): + times = [] + values = [] + for time, value in time_data.values(): + times.append(time) + values.append(value) + + max_time = max(times) + for function_name, (time, value) in time_data.items(): + percentage_ratio = (max_time / time) + message = f"{function_name}: {time} -" + if percentage_ratio == 1.0: + message = f"{message} base line" + else: + percentage_increase = (percentage_ratio * 100.0) + message = f"{message} {percentage_ratio}x / {percentage_increase}% faster" + print(message) + +run_functions(get_function_list, obj) +process_results(get_timer_dict) + +# print(np_GetSkinWeights())