├── .DS_Store ├── pic ├── MLS-rigid.mp4 ├── cuboid-orig.png ├── soldier-orig.png ├── soldier-rest.jpg ├── cuboid-MLS-sim.png ├── cuboid-MLS-rigid.png ├── soldier-deformed.jpg ├── cuboid-MLS-sim-arap.png ├── cuboid-MLS-rigid-arap.png └── soldier-MLS-rigid-arap.png ├── .vs └── PoissonMLS │ └── v14 │ └── .suo ├── PoissonMLS.vcxproj.user ├── PoissonMLS.xcodeproj ├── project.xcworkspace │ ├── xcuserdata │ │ └── kaji.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ ├── UserInterfaceState (air2's conflicted copy 2016-12-13).xcuserstate │ │ │ └── xcdebugger │ │ │ └── Expressions.xcexplist │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── cageDeformer.xccheckout ├── xcuserdata │ └── kaji.xcuserdatad │ │ ├── xcschemes │ │ ├── xcschememanagement.plist │ │ └── PoissonMLS.xcscheme │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist └── project.pbxproj ├── PoissonMLS ├── StdAfx.cpp ├── StdAfx.h ├── PoissonMLS.h └── PoissonMLS.cpp ├── PoissonMLS.user ├── PoissonMLS.sln ├── LICENSE ├── MayaPlugin.props ├── MayaPluginDebug.props ├── Makefile ├── deformerConst.h ├── README.md ├── blendAff.h ├── PoissonMLS.vcxproj ├── ui_PoissonMLS.py ├── laplacian.h ├── MeshMaya.h ├── distance.h ├── mayaHeaders.h ├── tetrise.h └── affinelib.h /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/.DS_Store -------------------------------------------------------------------------------- /pic/MLS-rigid.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/pic/MLS-rigid.mp4 -------------------------------------------------------------------------------- /pic/cuboid-orig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/pic/cuboid-orig.png -------------------------------------------------------------------------------- /pic/soldier-orig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/pic/soldier-orig.png -------------------------------------------------------------------------------- /pic/soldier-rest.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/pic/soldier-rest.jpg -------------------------------------------------------------------------------- /pic/cuboid-MLS-sim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/pic/cuboid-MLS-sim.png -------------------------------------------------------------------------------- /.vs/PoissonMLS/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/.vs/PoissonMLS/v14/.suo -------------------------------------------------------------------------------- /pic/cuboid-MLS-rigid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/pic/cuboid-MLS-rigid.png -------------------------------------------------------------------------------- /pic/soldier-deformed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/pic/soldier-deformed.jpg -------------------------------------------------------------------------------- /pic/cuboid-MLS-sim-arap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/pic/cuboid-MLS-sim-arap.png -------------------------------------------------------------------------------- /pic/cuboid-MLS-rigid-arap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/pic/cuboid-MLS-rigid-arap.png -------------------------------------------------------------------------------- /pic/soldier-MLS-rigid-arap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/pic/soldier-MLS-rigid-arap.png -------------------------------------------------------------------------------- /PoissonMLS.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /PoissonMLS.xcodeproj/project.xcworkspace/xcuserdata/kaji.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/PoissonMLS.xcodeproj/project.xcworkspace/xcuserdata/kaji.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PoissonMLS.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PoissonMLS.xcodeproj/project.xcworkspace/xcuserdata/kaji.xcuserdatad/UserInterfaceState (air2's conflicted copy 2016-12-13).xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shizuo-kaji/PoissonMLS/HEAD/PoissonMLS.xcodeproj/project.xcworkspace/xcuserdata/kaji.xcuserdatad/UserInterfaceState (air2's conflicted copy 2016-12-13).xcuserstate -------------------------------------------------------------------------------- /PoissonMLS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PoissonMLS/StdAfx.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | //----------------------------------------------------------------------------- 4 | //------ StdAfx.cpp : source file that includes just the standard includes 5 | //------ StdAfx.pch will be the pre-compiled header 6 | //------ StdAfx.obj will contain the pre-compiled type information 7 | //----------------------------------------------------------------------------- 8 | #include "StdAfx.h" 9 | -------------------------------------------------------------------------------- /PoissonMLS.xcodeproj/project.xcworkspace/xcuserdata/kaji.xcuserdatad/xcdebugger/Expressions.xcexplist: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /PoissonMLS.xcodeproj/xcuserdata/kaji.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PoissonMLS.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 2AA6F2111920C94E005B4AF8 16 | 17 | primary 18 | 19 | 20 | 2AA6F2271920CDC0005B4AF8 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /PoissonMLS.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | C:\Program Files\Autodesk\Maya2016\bin\maya.exe 5 | true 6 | WindowsLocalDebugger 7 | $(USERPROFILE)\Documents\maya\ 8 | 9 | 10 | $(USERPROFILE)\Documents\maya\ 11 | WindowsLocalDebugger 12 | 13 | -------------------------------------------------------------------------------- /PoissonMLS.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PoissonMLS", "PoissonMLS.vcxproj", "{67131301-2A24-437B-8B18-9498812D7B0E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {67131301-2A24-437B-8B18-9498812D7B0E}.Debug|x64.ActiveCfg = Debug|x64 15 | {67131301-2A24-437B-8B18-9498812D7B0E}.Debug|x64.Build.0 = Debug|x64 16 | {67131301-2A24-437B-8B18-9498812D7B0E}.Release|x64.ActiveCfg = Release|x64 17 | {67131301-2A24-437B-8B18-9498812D7B0E}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /PoissonMLS/StdAfx.h: -------------------------------------------------------------------------------- 1 | 2 | //----------------------------------------------------------------------------- 3 | //- StdAfx.h : include file for standard system include files, 4 | //- or project specific include files that are used frequently, 5 | //- but are changed infrequently 6 | //----------------------------------------------------------------------------- 7 | #pragma once 8 | 9 | //----------------------------------------------------------------------------- 10 | //----- This file is preprocessor symbol driven. 11 | //----- Define: 12 | //----- _PYTHON_MODULE_ to include and import Python headers and libs in your project. 13 | //#define _PYTHON_MODULE_ 14 | //----- _MAYA_QT_ to include and import Maya QT headers and libs in your project. 15 | //#define _MAYA_QT_ 16 | //----- _MAYA_VP2_ to include and import Maya Viewport 2.0 headers and libs in your project. 17 | //#define _MAYA_VP2_ 18 | 19 | #include "../mayaHeaders.h" 20 | #ifdef NT_PLUGIN 21 | #include 22 | #else 23 | #define _T(a) a 24 | #endif 25 | 26 | //----------------------------------------------------------------------------- 27 | //----- If you need MFnPlugin definition more than once 28 | //- MNoVersionString is needed on MacOS and Linux to avoid multiple MApiVersion definition 29 | //#define MNoVersionString 30 | //- MNoPluginEntry is needed on Windows platform to avoid multiple DllMain definition 31 | //#define MNoPluginEntry 32 | //#include 33 | -------------------------------------------------------------------------------- /MayaPlugin.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(SolutionDir)$(Configuration)\ 7 | $(SolutionDir)$(Configuration)\ 8 | .mll 9 | 10 | 11 | 12 | Full 13 | 14 | 15 | 16 | 17 | Speed 18 | _WINDLL;NT_PLUGIN;NDEBUG;REQUIRE_IOSTREAM;_WIN64%(PreprocessorDefinitions) 19 | true 20 | C:\Program Files\Autodesk\Maya2016\include; 21 | 22 | 23 | /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions) 24 | OpenMaya.lib;OpenMayaRender.lib;OpenMayaAnim.lib;Foundation.lib; 25 | C:\Program Files\Autodesk\Maya2016\lib 26 | false 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /MayaPluginDebug.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(SolutionDir)$(Configuration)\ 7 | $(SolutionDir)$(Configuration)\ 8 | .mll 9 | <_PropertySheetDisplayName>MayaPluginDebug 10 | 11 | 12 | 13 | Disabled 14 | 15 | 16 | 17 | 18 | Speed 19 | _WINDLL;NT_PLUGIN;REQUIRE_IOSTREAM;_WIN64%(PreprocessorDefinitions) 20 | true 21 | C:\Program Files\Autodesk\Maya2016\include; 22 | 23 | 24 | /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions) 25 | OpenMaya.lib;OpenMayaRender.lib;OpenMayaAnim.lib;Foundation.lib; 26 | C:\Program Files\Autodesk\Maya2016\lib 27 | true 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /PoissonMLS.xcodeproj/project.xcworkspace/xcshareddata/cageDeformer.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | E7C2CEA8-CE88-4D97-9284-A9874900D32E 9 | IDESourceControlProjectName 10 | cageDeformer 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 912A53A2095059FA181F9D8B8218E738CEF205A1 14 | github.com:shizuo-kaji/CageDeformerMaya.git 15 | 16 | IDESourceControlProjectPath 17 | cageDeformer.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 912A53A2095059FA181F9D8B8218E738CEF205A1 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | github.com:shizuo-kaji/CageDeformerMaya.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 912A53A2095059FA181F9D8B8218E738CEF205A1 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 912A53A2095059FA181F9D8B8218E738CEF205A1 36 | IDESourceControlWCCName 37 | cageDeformer 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for OS-X 2 | 3 | MAYA_LOCATION = /Applications/Autodesk/maya 4 | 5 | PROJ1 = PoissonMLS 6 | SOURCE1 = ./$(PROJ1)/$(PROJ1).cpp 7 | OBJECT1 = ./$(PROJ1).o 8 | ASM1 = ./$(PROJ1).s 9 | 10 | INCLUDES = -I$(MAYA_LOCATION)/devkit/include/ -I./ -I../ -I/usr/local/include/eigen3/ 11 | LIBS = -L$(MAYA_LOCATION)/Maya.app/Contents/MacOS -lOpenMaya -lOpenMayaAnim -lOpenMayaRender -lOpenMayaUI -lFoundation 12 | ISYSROOT = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk 13 | 14 | #compiler options 15 | CC = /usr/bin/g++ 16 | LD = /usr/bin/g++ 17 | CLANG = /usr/bin/clang 18 | 19 | CFLAGS = -DCC_GNU_ -DOSMac_ -DOSMacOSX_ \ 20 | -DOSMac_MachO_ -D_LANGUAGE_C_PLUS_PLUS \ 21 | -include "$(MAYA_LOCATION)/devkit/include/maya/OpenMayaMac.h" \ 22 | -DMAC_PLUGIN -D_BOOL -DREQUIRE_IOSTREAM -O2 -mavx 23 | #CFLAGS += -fopenmp 24 | C++FLAGS = $(CFLAGS) $(WARNFLAGS) $(ERROR_FLAGS) -fno-gnu-keywords 25 | LDFLAGS = $(C++FLAGS) 26 | DYNLIB_LOCATION = $(MAYA_LOCATION)/Maya.app/Contents/MacOS 27 | 28 | LDFLAGS += -isysroot $(ISYSROOT) $(ARCH_FLAGS) -headerpad_max_install_names -bundle 29 | 30 | LDFLAGS += -Wl,-exported_symbol,__Z16initializePlugin7MObject \ 31 | -Wl,-exported_symbol,__Z18uninitializePlugin7MObject 32 | 33 | LREMAP = -Wl,-executable_path,"$(DYNLIB_LOCATION)" 34 | LDFLAGS += -L"$(DYNLIB_LOCATION)" $(LREMAP) 35 | 36 | .PHONY: all install clean 37 | 38 | 39 | all: $(PROJ1) 40 | 41 | $(PROJ1): $(OBJECT1) 42 | $(LD) $(LDFLAGS) $(LIBS) $^ -o $@.bundle 43 | 44 | $(OBJECT1): $(ASM1) 45 | $(CLANG) -c $^ 46 | 47 | $(ASM1): $(SOURCE1) 48 | $(CC) -S $(INCLUDES) $(C++FLAGS) $^ 49 | 50 | install: 51 | mv $(PROJ1).bundle /Users/Shared/Autodesk/maya/plug-ins/ 52 | 53 | clean: 54 | rm -f $(PROJ1).bundle $(OBJECT1) $(ASM1) 55 | -------------------------------------------------------------------------------- /deformerConst.h: -------------------------------------------------------------------------------- 1 | // 2 | // deformerConst.h 3 | // 4 | 5 | #pragma once 6 | 7 | #ifndef ProbeDeformer_deformerConst_h 8 | #define ProbeDeformer_deformerConst_h 9 | 10 | // parametrisation mode 11 | #define BM_SRL 0 // sym^+ so(3) R^3 12 | #define BM_SSE 1 // sym^+ se(3) 13 | #define BM_LOG3 3 // gl(3) R^3 14 | #define BM_LOG4 4 // aff(3) 15 | #define BM_SQL 5 // Sym quat R^3 16 | #define BM_SlRL 6 // Sym so(3) R^3 17 | #define BM_AFF 10 // Aff(3) 18 | #define BM_OFF -1 19 | 20 | // weight normalisation mode 21 | #define NM_NONE 0 22 | #define NM_LINEAR 1 23 | #define NM_SOFTMAX 2 24 | 25 | // weight mode 26 | #define WM_INV_DISTANCE 0 27 | #define WM_CUTOFF_DISTANCE 1 28 | #define WM_DRAW 2 29 | #define WM_HARMONIC 16 30 | #define WM_HARMONIC_ARAP 16 31 | #define WM_HARMONIC_COTAN 17 32 | #define WM_HARMONIC_TRANS 18 33 | 34 | // tetrahedra construction mode 35 | #define TM_FACE 0 36 | #define TM_EDGE 1 37 | #define TM_VERTEX 2 38 | #define TM_VFACE 3 // for each vertex and an adjacent face, make a tet by adding the face normal to the vertex 39 | 40 | // cage mode 41 | #define CM_MVC 8 42 | #define CM_MLS 16 43 | #define CM_MLS_AFF 16 44 | #define CM_MLS_SIM 17 45 | #define CM_MLS_RIGID 18 46 | 47 | // MLS mode 48 | #define MLS_OFF -1 49 | #define MLS_AFF 0 50 | #define MLS_RIGID 1 51 | #define MLS_SIM 2 52 | #define MLS_POSITIVE_DET 4 53 | 54 | 55 | // constraint mode 56 | #define CONSTRAINT_NEIGHBOUR 0 57 | #define CONSTRAINT_CLOSEST 1 58 | 59 | // stiffness mode 60 | #define SM_NONE 0 61 | #define SM_PAINT 1 62 | #define SM_LEARN 2 63 | 64 | // visualisation mode 65 | #define VM_OFF 0 66 | #define VM_ENERGY 1 67 | #define VM_EFFECT 2 68 | #define VM_CONSTRAINT 3 69 | #define VM_STIFFNESS 4 70 | 71 | // error codes 72 | #define ERROR_ARAP_PRECOMPUTE 1 73 | #define INCOMPATIBLE_MESH 2 74 | #define ERROR_ATTR 4 75 | #define ERROR_MLS_SINGULAR 8 76 | 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PoissonMLS plugin for Maya 2 | /** 3 | * @brief Poisson MLS Deformer plugins for Maya 4 | * @section LICENSE The MIT License 5 | * @section requirements: Eigen 3: http://eigen.tuxfamily.org/ 6 | * @section Autodesk Maya: http://www.autodesk.com/products/autodesk-maya/overview 7 | * @section (included) AffineLib: https://github.com/shizuo-kaji/AffineLib 8 | * @version 0.10 9 | * @date 19/Nov/2016 10 | * @author Shizuo KAJI 11 | */ 12 | 13 | ## The plugins 14 | This is a deformer plugin based on the Moving Least Square deformation 15 | and the Poisson mesh editing techniques. 16 | The algorithm is presented at MEIS2016: 17 | 18 | http://www.skaji.org/files/MEIS2016-MLS.pdf 19 | 20 | 21 | ## How to compile: 22 | - Get devkit at https://www.autodesk.com/developmaya 23 | - Mac OS: Look at the included Xcode project file 24 | - Windows: Look at the included Visual Studio project. __DO NOT__ turn on AVX instructions. 25 | - Other: Look at the included Makefile 26 | - on some systems, specifying the compiler option -DEIGEN_DONT_VECTORIZE may be necessary to avoid compilation errors (thank giordi91 for this information) 27 | 28 | 29 | ## How to use: 30 | - put the plugins in "MAYA_PLUG_IN_PATH" 31 | - put the UI python script in "MAYA_SCRIPT_PATH" 32 | - open script editor in Maya and type in the following Python command: 33 | 34 | ```python 35 | import ui_PoissonMLS as ui 36 | ui.UI_PoissonMLS() 37 | ``` 38 | 39 | - Select multiple objects which you would like to make control points. 40 | - While holding the shift key, select the target mesh to be deformed. 41 | (that is, the target mesh is the last among the selected objects.) 42 | - Create deformer node from the menu of the included UI script. 43 | - By default, the weight(influence) of each control point is connected by the scale attribute. 44 | 45 | ## LIMITATION: 46 | The "poisson" option works only with clean meshes. 47 | First apply "Cleanup" from "Mesh" menu 48 | to remove zero faces and edges, non-manifold geometry, etc. 49 | -------------------------------------------------------------------------------- /PoissonMLS/PoissonMLS.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma comment(linker, "/export:initializePlugin /export:uninitializePlugin") 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "../affinelib.h" 12 | #include "../deformerConst.h" 13 | #include "../tetrise.h" 14 | #include "../MeshMaya.h" 15 | #include "../laplacian.h" 16 | #include "../blendAff.h" 17 | #include "../distance.h" 18 | 19 | using namespace Eigen; 20 | 21 | class MLSDeformerNode : public MPxDeformerNode{ 22 | public: 23 | MLSDeformerNode(): numPrb(0) {}; 24 | virtual MStatus deform( MDataBlock& data, MItGeometry& itGeo, const MMatrix &localToWorldMatrix, unsigned int mIndex ); 25 | static void* creator(); 26 | static MStatus initialize(); 27 | 28 | static MTypeId id; 29 | static MString nodeName; 30 | static MObject aMLSMode; 31 | static MObject aNormExponent; 32 | static MObject aWeightMode; 33 | static MObject aEffectRadius; 34 | static MObject aNormaliseWeight; 35 | static MObject aAreaWeighted; 36 | static MObject aNeighbourWeighting; 37 | static MObject aPositiveWeight; 38 | static MObject aCtlPoints; 39 | static MObject aInitCtlPoints; 40 | static MObject aRecompMLS; 41 | static MObject aRecompARAP; 42 | static MObject aPoisson; 43 | static MObject aCtlWeight; 44 | static MObject aTetMode; 45 | static MObject aIteration; 46 | static MObject aConstraintMode; 47 | static MObject aConstraintWeight; 48 | static MObject aConstraintRadius; 49 | 50 | 51 | 52 | private: 53 | Distance D; 54 | Laplacian mesh; 55 | std::vector< std::vector > w; // weight for the target mesh points 56 | int numPrb; 57 | int isError; 58 | // mesh 59 | std::vector< edge > edgeList; 60 | std::vector vertexList; 61 | std::vector faceList; 62 | std::vector pts; 63 | std::vector constraint; 64 | std::vector icenter; 65 | std::vector tetCenter; // location of tet 66 | // 67 | std::vector p; 68 | std::vector PPI; 69 | std::vector trPP; 70 | std::vector Q; 71 | }; 72 | 73 | -------------------------------------------------------------------------------- /PoissonMLS.xcodeproj/xcuserdata/kaji.xcuserdatad/xcschemes/PoissonMLS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /blendAff.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file blendAff.h 3 | * @brief blending ffine transformations 4 | * @section LICENSE The MIT License 5 | * @section requirements: Eigen library 6 | * @version 0.10 7 | * @date Oct. 2016 8 | * @author Shizuo KAJI 9 | */ 10 | 11 | #pragma once 12 | 13 | #include 14 | #include 15 | #include "affinelib.h" 16 | #include "deformerConst.h" 17 | 18 | using namespace Eigen; 19 | using namespace AffineLib; 20 | 21 | class BlendAff { 22 | public: 23 | std::vector logR,R,logS,S,logGL; 24 | std::vector logSE,SE,logAff,Aff; 25 | std::vector L; 26 | std::vector quat; 27 | std::vector centre; 28 | 29 | int num; 30 | bool rotationConsistency; 31 | 32 | BlendAff(int n=0){ 33 | num = n; 34 | Aff.resize(num); 35 | centre.resize(num); 36 | L.resize(num); 37 | }; 38 | 39 | void setNum(int n){ 40 | num = n; 41 | Aff.resize(num); 42 | centre.resize(num); 43 | L.resize(num); 44 | } 45 | void parametrise(int mode); 46 | void clearRotation(); 47 | }; 48 | 49 | 50 | void BlendAff::parametrise(int mode){ 51 | if(mode == BM_SRL || mode == BM_SSE || mode == BM_SQL){ 52 | R.resize(num); logS.resize(num); S.resize(num); 53 | for(int i=0;i Q(R[i].transpose()); 85 | quat[i] << Q.x(), Q.y(), Q.z(), Q.w(); 86 | S[i]=expSym(logS[i]); 87 | } 88 | break; 89 | } 90 | }else if(mode == BM_LOG3){ 91 | logGL.resize(num); 92 | for(int i=0;i 2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {67131301-2A24-437B-8B18-9498812D7B0E} 15 | PoissonMLS 16 | PoissonMLS 17 | 10.0.17134.0 18 | 19 | 20 | 21 | DynamicLibrary 22 | v141 23 | 24 | 25 | DynamicLibrary 26 | v141 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | $(USERPROFILE)\Documents\maya\ 40 | $(USERPROFILE)\Documents\maya\ 41 | 42 | 43 | $(USERPROFILE)\Documents\maya\ 44 | $(USERPROFILE)\Documents\maya\ 45 | 46 | 47 | 48 | /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions) 49 | C:\Program Files\Autodesk\Maya2016\lib 50 | 51 | 52 | c:\usr\include\eigen;$(USERPROFILE)\Dropbox\maple\mayac\;C:\Program Files\Autodesk\Maya2016\include;%(AdditionalIncludeDirectories) 53 | NotSet 54 | true 55 | /bigobj %(AdditionalOptions) 56 | 57 | 58 | 59 | 60 | c:\usr\include\eigen;C:\Program Files\Autodesk\Maya2019\include;%(AdditionalIncludeDirectories) 61 | NotSet 62 | /bigobj %(AdditionalOptions) 63 | 64 | 65 | C:\Program Files\Autodesk\Maya2019\lib 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /ui_PoissonMLS.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # User interface for Poisson MLS Deformer plugin 4 | # The last object in the selected ones will be the target while the others will serve as control points 5 | 6 | # @author Shizuo KAJI 7 | # @date 2016/11/14 8 | 9 | # for debug 10 | #import debugmaya 11 | #debugmaya.startDebug() 12 | 13 | # Import Maya Modules 14 | import maya.cmds as cmds 15 | import pymel.core as pm 16 | 17 | deformerTypes = ["PoissonMLS"] 18 | 19 | for type in deformerTypes: 20 | try: 21 | cmds.loadPlugin(type) 22 | except: 23 | print("Plugin %s already loaded" %(type)) 24 | 25 | ## prepare interface 26 | class UI_PoissonMLS: 27 | uiID = "PoissonMLS" 28 | title = "PoissonMLS" 29 | deformers = [] 30 | probes = {} 31 | 32 | ## Constructor 33 | def __init__(self): 34 | if pm.window(self.uiID, exists=True): 35 | pm.deleteUI(self.uiID) 36 | win = pm.window(self.uiID, title=self.title, menuBar=True) 37 | with win: 38 | pm.menu( label='Create', tearOff=True ) 39 | for type in deformerTypes: 40 | pm.menuItem( label=type, c=pm.Callback( self.initPlugin, type) ) 41 | self._parentLayout = pm.columnLayout( adj=True ) 42 | with self._parentLayout: 43 | self.createUISet() 44 | 45 | def createUISet(self): 46 | self._childLayout = pm.columnLayout( adj=True ) 47 | with self._childLayout: 48 | self.deformers = [pm.ls(type=deformerTypes[i]) for i in range(len(deformerTypes))] 49 | for i in range(len(deformerTypes)): 50 | for node in self.deformers[i]: 51 | self.probes[node] = pm.listConnections(node.cp) 52 | # specific 53 | for node in self.deformers[0]: 54 | frameLayout = pm.frameLayout( label=node.name(), collapsable = True) 55 | with frameLayout: 56 | self.createCommonAttr(node, deformerTypes[0]) 57 | indices = cmds.getAttr(node+".cp", multiIndices=True) 58 | if indices: 59 | for j in indices: 60 | with pm.rowLayout(numberOfColumns=1) : 61 | pm.attrFieldSliderGrp(label=node.ctlw[j].getAlias(), min=0, max=10.0, attribute=node.ctlw[j]) 62 | 63 | # create deformer node and connection 64 | def initPlugin(self, deformerType): 65 | # get transform nodes for the selected objects 66 | transforms = pm.selected(tr=1) 67 | if not transforms: 68 | return 69 | pm.select( transforms[-1]) # the deformer is attached to the last selected object 70 | node = pm.ls(cmds.deformer(type=deformerType)[0])[0] 71 | cmds.makePaintable(deformerType, 'weights', attrType='multiFloat', shapeMode='deformer') 72 | if len(transforms)>1: 73 | self.addProbe(node,deformerType,transforms[:-1]) 74 | self.updateUI() 75 | 76 | # add selected transform as a new probe 77 | def addProbe(self,node,deformerType,newProbes): 78 | indexes = cmds.getAttr(node+".cp", multiIndices=True) 79 | if not indexes: 80 | n=0 81 | else: 82 | n=indexes[-1]+1 83 | # connect pm first to avoid unnecessary arap computations 84 | for j in range(len(newProbes)): 85 | cmds.connectAttr(newProbes[j]+".center", node+".cp[%s]" %(j+n)) 86 | cmds.connectAttr(newProbes[j]+".scaleX", node+".ctlw[%s]" %(j+n)) 87 | node.icp[j+n].set(node.cp[j+n].get()) 88 | 89 | # add selected transform as a new probe 90 | def addSelectedProbe(self,node,deformerType): 91 | newProbes = pm.selected(tr=1) 92 | self.addProbe(node,deformerType,newProbes) 93 | self.updateUI() 94 | 95 | # delete deformer node 96 | def deleteNode(self,node): 97 | cmds.delete(node.name()) 98 | self.updateUI() 99 | 100 | # redraw UI 101 | def updateUI(self): 102 | pm.deleteUI( self._childLayout ) 103 | pm.setParent(self._parentLayout) 104 | self.createUISet() 105 | 106 | def createCommonAttr(self,node,deformerType): 107 | with pm.rowLayout(numberOfColumns=3) : 108 | pm.button( l="Add selection to ctrl points", c=pm.Callback( self.addSelectedProbe, node, deformerType) ) 109 | pm.button( l="Delete deformer", c=pm.Callback( self.deleteNode, node)) 110 | pm.attrControlGrp( label="Poisson", attribute= node.poisson) 111 | with pm.rowLayout(numberOfColumns=4) : 112 | pm.attrControlGrp( label="MLS mode", attribute= node.mlsm) 113 | pm.attrControlGrp( label="area weight", attribute= node.aw) 114 | pm.attrControlGrp( label="neighbour weighting", attribute= node.nghbrw) 115 | pm.attrFieldSliderGrp( label="iteration", min=1, max=20, attribute=node.it) 116 | with pm.rowLayout(numberOfColumns=4) : 117 | pm.attrControlGrp( label="Weight mode", attribute= node.wtm) 118 | pm.attrFieldSliderGrp(label="effect radius", min=0.001, max=20.0, attribute=node.er) 119 | pm.attrControlGrp( label="normalise weight", attribute= node.nw) 120 | pm.attrControlGrp( label="normExponent", attribute=node.ne) 121 | with pm.rowLayout(numberOfColumns=4) : 122 | pm.attrControlGrp( label="tet mode", attribute= node.tm) 123 | pm.attrControlGrp( label="constraint mode", attribute= node.ctm) 124 | pm.attrFieldSliderGrp( label="constraint weight", min=0.001, max=1000, attribute=node.cw) 125 | pm.attrFieldSliderGrp(label="constraint radius", min=0.001, max=10.0, attribute=node.cr) 126 | 127 | -------------------------------------------------------------------------------- /laplacian.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ARAP.h 3 | * @brief ARAP related functions 4 | * @section LICENSE The MIT License 5 | * @section requirements: Eigen library 6 | * @version 0.10 7 | * @date Aug. 2014 8 | * @author Shizuo KAJI 9 | */ 10 | 11 | #pragma once 12 | 13 | #include 14 | #include 15 | 16 | #include "deformerConst.h" 17 | 18 | //#define _SuiteSparse 19 | //#define _CERES 20 | 21 | using namespace Eigen; 22 | 23 | typedef SparseMatrix SpMat; 24 | typedef Triplet T; 25 | 26 | #ifdef _SuiteSparse 27 | #include 28 | typedef CholmodDecomposition SpSolver; 29 | #else 30 | typedef SimplicialLDLT SpSolver; 31 | //typedef SimplicialLLT SpSolver; 32 | //typedef SparseLU SpSolver; 33 | #endif 34 | 35 | #ifdef _CERES 36 | #include "ceres/ceres.h" 37 | #include "glog/logging.h" 38 | #endif 39 | 40 | 41 | 42 | class Laplacian { 43 | public: 44 | int numTet; // the number of tetrahedra 45 | int dim; // the dimension of the system including ghost vertices 46 | double transWeight; 47 | SpSolver solver; 48 | SpMat constraintMat; 49 | SpMat laplacian; 50 | std::vector tetList; 51 | std::vector tetMatrix,tetMatrixInverse; 52 | std::vector tetWeight; 53 | std::vector< std::pair > constraintWeight; // [i,w] = i-th vertex is constrained with weight w 54 | MatrixXd constraintVal; // i-th row = value of i-th constraint 55 | MatrixXd Sol; 56 | Laplacian(): numTet(0), tetMatrix(0), tetMatrixInverse(0), tetWeight(0), constraintWeight(0), transWeight(0) { 57 | }; 58 | int ARAPprecompute(); 59 | void ARAPSolve(const std::vector& targetMat); 60 | void harmonicSolve(); 61 | int cotanPrecompute(); 62 | void computeTetMatrixInverse(); 63 | }; 64 | 65 | 66 | // construct the system of ARAP with soft constraints 67 | int Laplacian::ARAPprecompute(){ 68 | std::vector tripletListMat(0); 69 | tripletListMat.reserve(numTet*16); 70 | Matrix4d Hlist; 71 | Matrix4d diag=Matrix4d::Identity(); 72 | diag(3,3)=transWeight; 73 | for(int i=0;i tripletListF(0),tripletListC(0); 86 | for(int i=0;i Cleanup => Remove zero edges, faces"); 101 | return ERROR_ARAP_PRECOMPUTE; 102 | } 103 | return 0; 104 | } 105 | 106 | // solve the ARAP system 107 | void Laplacian::ARAPSolve(const std::vector& targetMat){ 108 | Matrix4d Glist; 109 | Matrix4d diag=Matrix4d::Identity(); 110 | diag(3,3)=transWeight; 111 | MatrixXd G = MatrixXd::Zero(dim,3); 112 | for(int i=0;i tripletListMat(0); 135 | tripletListMat.reserve(numTet*9); 136 | for(int i=0;i l(3); 138 | l[0] << tetMatrix[i](2,0)-tetMatrix[i](1,0), tetMatrix[i](2,1)-tetMatrix[i](1,1), tetMatrix[i](2,2)-tetMatrix[i](1,2); 139 | l[1] << tetMatrix[i](0,0)-tetMatrix[i](2,0), tetMatrix[i](0,1)-tetMatrix[i](2,1), tetMatrix[i](0,2)-tetMatrix[i](2,2); 140 | l[2] << tetMatrix[i](1,0)-tetMatrix[i](0,0), tetMatrix[i](1,1)-tetMatrix[i](0,1), tetMatrix[i](1,2)-tetMatrix[i](0,2); 141 | double w = tetWeight[i]/(l[1].cross(l[2]).norm()); 142 | for(int j=0;j<3;j++){ 143 | int j1=(j+1) % 3; 144 | int j2=(j+2) % 3; 145 | tripletListMat.push_back(T(tetList[4*i+j],tetList[4*i+j], w*l[j].dot(l[j1]+l[j2]))); 146 | tripletListMat.push_back(T(tetList[4*i+j],tetList[4*i+j1], -w*l[j].dot(l[j1]))); 147 | tripletListMat.push_back(T(tetList[4*i+j],tetList[4*i+j2], -w*l[j].dot(l[j2]))); 148 | } 149 | } 150 | laplacian.resize(dim, dim); 151 | laplacian.setZero(); 152 | laplacian.setFromTriplets(tripletListMat.begin(), tripletListMat.end()); 153 | // set soft constraint 154 | int numConstraints = constraintWeight.size(); 155 | std::vector tripletListF(0),tripletListC(0); 156 | for(int i=0;i Cleanup => Remove zero edges, faces"); 170 | return ERROR_ARAP_PRECOMPUTE; 171 | } 172 | return 0; 173 | } 174 | 175 | void Laplacian::computeTetMatrixInverse(){ 176 | tetMatrixInverse.resize(numTet); 177 | for(int i=0;i 16 | 17 | using namespace Tetrise; 18 | 19 | 20 | 21 | // get face list 22 | int makeFaceTet(MDataBlock& data, MObject& input, MObject& inputGeom, unsigned int mIndex, const std::vector& pts, 23 | std::vector& tetList, std::vector& tetMatrix, std::vector& tetWeight){ 24 | // returns total number of pts including ghost ones 25 | // read mesh data 26 | int numPts = (int) pts.size(); 27 | MStatus status; 28 | MArrayDataHandle hInput = data.outputArrayValue( input, &status ); 29 | CHECK_MSTATUS_AND_RETURN_IT( status ); 30 | status = hInput.jumpToElement( mIndex ); 31 | CHECK_MSTATUS_AND_RETURN_IT( status ); 32 | MObject oInputGeom = hInput.outputValue().child( inputGeom ).asMesh(); 33 | MFnMesh inputMesh(oInputGeom); 34 | // face list 35 | MIntArray count, triangles; 36 | inputMesh.getTriangles( count, triangles ); 37 | std::vector faceList(triangles.length()); 38 | for(int i=0;i vList; 43 | std::vector eList; 44 | makeTetList(TM_FACE, numPts, faceList, eList, vList, tetList); 45 | makeTetMatrix(TM_FACE, pts, tetList, faceList, eList, vList, tetMatrix, tetWeight); 46 | return numPts + (int)tetList.size()/4; 47 | } 48 | 49 | // make face list 50 | void makeFaceList(MObject& mesh, std::vector& faceList, std::vector& faceCount, 51 | bool isSymmetric=false){ 52 | if( isSymmetric ){ 53 | MItMeshPolygon iter(mesh); 54 | MIntArray faceVertices; 55 | faceList.clear(); 56 | for(int i=0; ! iter.isDone(); i++){ 57 | iter.getVertices(faceVertices); 58 | int count=faceVertices.length(); 59 | if(count==3){ 60 | faceCount.push_back(1); 61 | faceList.push_back(faceVertices[0]); 62 | faceList.push_back(faceVertices[1]); 63 | faceList.push_back(faceVertices[2]); 64 | }else{ 65 | for(int j=0;j& vertexList){ 88 | int numPts = MFnMesh(mesh).numVertices(); 89 | MItMeshPolygon iter(mesh); 90 | MIntArray faceVertices; 91 | vertexList.resize(numPts); 92 | for(int i=0;i& pts, std::vector& tetList, 109 | std::vector& faceList, std::vector& edgeList, 110 | std::vector& vertexList, std::vector& tetMat, std::vector& tetWeight){ 111 | // returns total number of pts including ghost ones 112 | // read mesh data 113 | int numPts = (int) pts.size(); 114 | MStatus status; 115 | MArrayDataHandle hInput = data.outputArrayValue( input, &status ); 116 | CHECK_MSTATUS_AND_RETURN_IT( status ); 117 | status = hInput.jumpToElement( mIndex ); 118 | CHECK_MSTATUS_AND_RETURN_IT( status ); 119 | MObject oInputGeom = hInput.outputValue().child( inputGeom ).asMesh(); 120 | std::vector faceCount; 121 | makeFaceList(oInputGeom, faceList, faceCount); 122 | makeVertexList(oInputGeom, vertexList); 123 | makeEdgeList(faceList, edgeList); 124 | int dim=makeTetList(tetMode, numPts, faceList, edgeList, vertexList, tetList); 125 | makeTetMatrix(tetMode, pts, tetList, faceList, edgeList, vertexList, tetMat, tetWeight); 126 | return dim; 127 | } 128 | 129 | // visualise vertex assigned values 130 | void visualise(MDataBlock& data, MObject& outputGeom, std::vector& ptsColour){ 131 | // load target mesh output 132 | MStatus status; 133 | MArrayDataHandle outputArray = data.outputArrayValue(outputGeom , &status ); 134 | MDataHandle hOutput = outputArray.inputValue(&status); 135 | MFnMesh outMesh(hOutput.data()); 136 | MColorArray Colours; 137 | MIntArray Index; 138 | // set vertex colour 139 | for(int i=0;i& m){ 149 | int numPrb=handle.elementCount(); 150 | m.resize(numPrb); 151 | MMatrix mat; 152 | for(int i=0;i& V){ 164 | int num=handle.elementCount(); 165 | V.resize(num); 166 | MVector v; 167 | for(int i=0;i& values){ 177 | MStatus status; 178 | MArrayDataBuilder builder(attribute, (int)values.size(), &status); 179 | for(int i=0;i& indices){ 189 | MStatus status; 190 | MArrayDataHandle outputArray = data.outputArrayValue(attribute); 191 | MArrayDataBuilder builder=outputArray.builder(); 192 | std::set::iterator iter; 193 | for(iter = indices.begin(); iter != indices.end(); iter++){ 194 | builder.removeElement(*iter); 195 | } 196 | outputArray.set(builder); 197 | } 198 | 199 | 200 | -------------------------------------------------------------------------------- /distance.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "deformerConst.h" 8 | 9 | using namespace Eigen; 10 | 11 | typedef SparseMatrix SpMat; 12 | typedef Triplet T; 13 | 14 | class Distance { 15 | 16 | public: 17 | std::vector< std::vector > distPts, distTet; // [i,j]-entry is the distance to the i-th handle to j-th element 18 | std::vector closestPts, closestTet; // [i]-entry is the index of the closest element to i-th handle 19 | int nHdl, nPts, nTet; 20 | Distance(){}; 21 | Distance(int _nHandle, int _nPts, int _nTet) { 22 | setNum(_nHandle, _nPts, _nTet); 23 | }; 24 | void setNum(int _nHandle, int _nPts, int _nTet); 25 | void findClosestPts(); 26 | void findClosestTet(); 27 | void computeCageDistPts(short cageMode, const std::vector& pts, const std::vector& cagePts, const std::vector& cageTetList); 28 | void computeCageDistTet(short cageMode, const std::vector& tetCenter, const std::vector& cagePts, const std::vector& cageTetList); 29 | void computeDistPts(const std::vector& pts, const std::vector& hdlPts); 30 | void computeDistTet(const std::vector& tetCenter, const std::vector& hdlPts); 31 | double distPtLin(Vector3d p,Vector3d a,Vector3d b); 32 | double distPtTri(Vector3d p,Vector3d a,Vector3d b,Vector3d c); 33 | void MVC(const std::vector& pts, const std::vector& cagePts, 34 | const std::vector& cageFaceList, std::vector< std::vector >& w); 35 | void normaliseWeight(short mode, std::vector& w); 36 | }; 37 | 38 | // initialise 39 | void Distance::setNum(int _nHandle, int _nPts, int _nTet){ 40 | nHdl = _nHandle; 41 | nPts = _nPts; 42 | nTet = _nTet; 43 | distPts.resize(nHdl); 44 | distTet.resize(nHdl); 45 | closestPts.resize(nHdl); 46 | closestTet.resize(nHdl); 47 | for(int i=0;i& pts, const std::vector& hdlPts){ 55 | for(int i=0;i& tetCenter, const std::vector& hdlPts){ 64 | for(int i=0;i& pts, const std::vector& cagePts, const std::vector& cageTetList){ 73 | switch (cageMode){ 74 | case TM_FACE: 75 | { 76 | for(int j=0;j& tetCenter, const std::vector& cagePts, const std::vector& cageTetList){ 123 | switch (cageMode){ 124 | case TM_FACE: 125 | { 126 | for(int j=0;j1){ 204 | return (a-p).norm(); 205 | }else if(t<0){ 206 | return (b-p).norm(); 207 | }else{ 208 | return (t*(a-b)-(p-b)).norm(); 209 | } 210 | } 211 | 212 | // compute distance between a triangle (abc) and a point p 213 | double Distance::distPtTri(Vector3d p, Vector3d a, Vector3d b, Vector3d c){ 214 | /// if p is in the outer half-space, it returns HUGE_VAL 215 | double s[4]; 216 | Vector3d n=(b-a).cross(c-a); 217 | if(n.squaredNorm()0 && v(1)>0 && v(0)+v(1)<1){ 231 | s[3]=k; 232 | }else{ 233 | s[3] = HUGE_VAL; 234 | } 235 | return min(min(min(s[0],s[1]),s[2]),s[3]); 236 | } 237 | 238 | // mean value coordinate 239 | void Distance::MVC(const std::vector& pts, const std::vector& cagePts, 240 | const std::vector& cageFaceList, std::vector< std::vector >& w) 241 | { 242 | int numPts=(int) pts.size(); 243 | int numCagePts=(int) cagePts.size(); 244 | int numFaces=(int) cageFaceList.size()/3; 245 | w.resize(numPts); 246 | #pragma omp parallel for 247 | for(int j=0; j mu(numCagePts), a(3), b(3); 250 | std::vector e(3),n(3); 251 | for(int i=0;i& w){ 275 | if(mode == NM_NONE || mode == NM_LINEAR){ 276 | double sum = std::accumulate(w.begin(), w.end(), 0.0); 277 | if ((sum > 1 || mode == NM_LINEAR) && sum != 0.0){ 278 | for (int i = 0; i < w.size(); i++){ 279 | w[i] /= sum; 280 | } 281 | } 282 | }else if(mode == NM_SOFTMAX){ 283 | double sum = 0.0; 284 | for (int i = 0; i < w.size(); i++){ 285 | sum += exp(w[i]); 286 | } 287 | for (int i = 0; i < w.size(); i++){ 288 | w[i] = exp(w[i])/sum; 289 | } 290 | } 291 | } 292 | -------------------------------------------------------------------------------- /PoissonMLS.xcodeproj/xcuserdata/kaji.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 40 | 52 | 53 | 54 | 56 | 68 | 69 | 70 | 72 | 84 | 85 | 86 | 88 | 100 | 101 | 102 | 104 | 116 | 117 | 118 | 120 | 132 | 133 | 134 | 136 | 148 | 149 | 150 | 152 | 164 | 165 | 166 | 168 | 180 | 181 | 182 | 184 | 196 | 197 | 198 | 200 | 212 | 213 | 214 | 216 | 228 | 229 | 230 | 232 | 244 | 245 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /PoissonMLS.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2A77D3AC1DD9A88D003AB5FB /* PoissonMLS.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2AA6F2121920C94E005B4AF8 /* PoissonMLS.bundle */; }; 11 | 2AA6F2161920C94E005B4AF8 /* PoissonMLS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AA6F2151920C94E005B4AF8 /* PoissonMLS.cpp */; }; 12 | 2AA6F2181920C94E005B4AF8 /* StdAfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AA6F2171920C94E005B4AF8 /* StdAfx.cpp */; }; 13 | 2AA6F2211920CA42005B4AF8 /* PoissonMLS.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AA6F2201920CA42005B4AF8 /* PoissonMLS.h */; }; 14 | 2AC02FB71E26168D0027E840 /* affinelib.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AC02FAF1E26168D0027E840 /* affinelib.h */; }; 15 | 2AC02FB81E26168D0027E840 /* blendAff.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AC02FB01E26168D0027E840 /* blendAff.h */; }; 16 | 2AC02FB91E26168D0027E840 /* deformerConst.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AC02FB11E26168D0027E840 /* deformerConst.h */; }; 17 | 2AC02FBA1E26168D0027E840 /* distance.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AC02FB21E26168D0027E840 /* distance.h */; }; 18 | 2AC02FBB1E26168D0027E840 /* laplacian.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AC02FB31E26168D0027E840 /* laplacian.h */; }; 19 | 2AC02FBC1E26168D0027E840 /* mayaHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AC02FB41E26168D0027E840 /* mayaHeaders.h */; }; 20 | 2AC02FBD1E26168D0027E840 /* MeshMaya.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AC02FB51E26168D0027E840 /* MeshMaya.h */; }; 21 | 2AC02FBE1E26168D0027E840 /* tetrise.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AC02FB61E26168D0027E840 /* tetrise.h */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXCopyFilesBuildPhase section */ 25 | 2AA6F2381920CEF4005B4AF8 /* CopyFiles */ = { 26 | isa = PBXCopyFilesBuildPhase; 27 | buildActionMask = 2147483647; 28 | dstPath = "/Users/Shared/Autodesk/maya/plug-ins"; 29 | dstSubfolderSpec = 0; 30 | files = ( 31 | 2A77D3AC1DD9A88D003AB5FB /* PoissonMLS.bundle in CopyFiles */, 32 | ); 33 | runOnlyForDeploymentPostprocessing = 0; 34 | }; 35 | /* End PBXCopyFilesBuildPhase section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 2A41C9A81DE2E61F00034FFC /* ui_PoissonMLS.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; name = ui_PoissonMLS.py; path = ../../Maya/plugin_deformer/ui_PoissonMLS.py; sourceTree = ""; }; 39 | 2AA6F2121920C94E005B4AF8 /* PoissonMLS.bundle */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = PoissonMLS.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 2AA6F2151920C94E005B4AF8 /* PoissonMLS.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PoissonMLS.cpp; sourceTree = ""; }; 41 | 2AA6F2171920C94E005B4AF8 /* StdAfx.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StdAfx.cpp; sourceTree = ""; }; 42 | 2AA6F2191920C94E005B4AF8 /* StdAfx.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StdAfx.h; sourceTree = ""; }; 43 | 2AA6F2201920CA42005B4AF8 /* PoissonMLS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PoissonMLS.h; sourceTree = ""; }; 44 | 2AA6F23A1920CF8D005B4AF8 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 45 | 2AA6F23B1920CF8D005B4AF8 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = ""; }; 46 | 2AC02FAF1E26168D0027E840 /* affinelib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = affinelib.h; sourceTree = ""; }; 47 | 2AC02FB01E26168D0027E840 /* blendAff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = blendAff.h; sourceTree = ""; }; 48 | 2AC02FB11E26168D0027E840 /* deformerConst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = deformerConst.h; sourceTree = ""; }; 49 | 2AC02FB21E26168D0027E840 /* distance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = distance.h; sourceTree = ""; }; 50 | 2AC02FB31E26168D0027E840 /* laplacian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = laplacian.h; sourceTree = ""; }; 51 | 2AC02FB41E26168D0027E840 /* mayaHeaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mayaHeaders.h; sourceTree = ""; }; 52 | 2AC02FB51E26168D0027E840 /* MeshMaya.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MeshMaya.h; sourceTree = ""; }; 53 | 2AC02FB61E26168D0027E840 /* tetrise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tetrise.h; sourceTree = ""; }; 54 | /* End PBXFileReference section */ 55 | 56 | /* Begin PBXFrameworksBuildPhase section */ 57 | 2AA6F20F1920C94E005B4AF8 /* Frameworks */ = { 58 | isa = PBXFrameworksBuildPhase; 59 | buildActionMask = 2147483647; 60 | files = ( 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 2AA6F2091920C94E005B4AF8 = { 68 | isa = PBXGroup; 69 | children = ( 70 | 2AC02FAF1E26168D0027E840 /* affinelib.h */, 71 | 2AC02FB01E26168D0027E840 /* blendAff.h */, 72 | 2AC02FB11E26168D0027E840 /* deformerConst.h */, 73 | 2AC02FB21E26168D0027E840 /* distance.h */, 74 | 2AC02FB31E26168D0027E840 /* laplacian.h */, 75 | 2AC02FB41E26168D0027E840 /* mayaHeaders.h */, 76 | 2AC02FB51E26168D0027E840 /* MeshMaya.h */, 77 | 2AC02FB61E26168D0027E840 /* tetrise.h */, 78 | 2A41C9A81DE2E61F00034FFC /* ui_PoissonMLS.py */, 79 | 2AA6F23A1920CF8D005B4AF8 /* LICENSE */, 80 | 2AA6F23B1920CF8D005B4AF8 /* README.md */, 81 | 2AA6F2141920C94E005B4AF8 /* PoissonMLS */, 82 | 2AA6F2131920C94E005B4AF8 /* Products */, 83 | ); 84 | sourceTree = ""; 85 | }; 86 | 2AA6F2131920C94E005B4AF8 /* Products */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 2AA6F2121920C94E005B4AF8 /* PoissonMLS.bundle */, 90 | ); 91 | name = Products; 92 | sourceTree = ""; 93 | }; 94 | 2AA6F2141920C94E005B4AF8 /* PoissonMLS */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 2AA6F2201920CA42005B4AF8 /* PoissonMLS.h */, 98 | 2AA6F2151920C94E005B4AF8 /* PoissonMLS.cpp */, 99 | 2AA6F2171920C94E005B4AF8 /* StdAfx.cpp */, 100 | 2AA6F2191920C94E005B4AF8 /* StdAfx.h */, 101 | ); 102 | path = PoissonMLS; 103 | sourceTree = ""; 104 | }; 105 | /* End PBXGroup section */ 106 | 107 | /* Begin PBXHeadersBuildPhase section */ 108 | 2AA6F2101920C94E005B4AF8 /* Headers */ = { 109 | isa = PBXHeadersBuildPhase; 110 | buildActionMask = 2147483647; 111 | files = ( 112 | 2AC02FBC1E26168D0027E840 /* mayaHeaders.h in Headers */, 113 | 2AC02FBB1E26168D0027E840 /* laplacian.h in Headers */, 114 | 2AC02FB91E26168D0027E840 /* deformerConst.h in Headers */, 115 | 2AA6F2211920CA42005B4AF8 /* PoissonMLS.h in Headers */, 116 | 2AC02FBA1E26168D0027E840 /* distance.h in Headers */, 117 | 2AC02FBD1E26168D0027E840 /* MeshMaya.h in Headers */, 118 | 2AC02FB81E26168D0027E840 /* blendAff.h in Headers */, 119 | 2AC02FB71E26168D0027E840 /* affinelib.h in Headers */, 120 | 2AC02FBE1E26168D0027E840 /* tetrise.h in Headers */, 121 | ); 122 | runOnlyForDeploymentPostprocessing = 0; 123 | }; 124 | /* End PBXHeadersBuildPhase section */ 125 | 126 | /* Begin PBXNativeTarget section */ 127 | 2AA6F2111920C94E005B4AF8 /* PoissonMLS */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = 2AA6F21D1920C94E005B4AF8 /* Build configuration list for PBXNativeTarget "PoissonMLS" */; 130 | buildPhases = ( 131 | 2AA6F20E1920C94E005B4AF8 /* Sources */, 132 | 2AA6F20F1920C94E005B4AF8 /* Frameworks */, 133 | 2AA6F2101920C94E005B4AF8 /* Headers */, 134 | 2AA6F2381920CEF4005B4AF8 /* CopyFiles */, 135 | ); 136 | buildRules = ( 137 | ); 138 | dependencies = ( 139 | ); 140 | name = PoissonMLS; 141 | productName = cageDeformer; 142 | productReference = 2AA6F2121920C94E005B4AF8 /* PoissonMLS.bundle */; 143 | productType = "com.apple.product-type.library.dynamic"; 144 | }; 145 | /* End PBXNativeTarget section */ 146 | 147 | /* Begin PBXProject section */ 148 | 2AA6F20A1920C94E005B4AF8 /* Project object */ = { 149 | isa = PBXProject; 150 | attributes = { 151 | LastUpgradeCheck = 0800; 152 | ORGANIZATIONNAME = "mcg-q"; 153 | }; 154 | buildConfigurationList = 2AA6F20D1920C94E005B4AF8 /* Build configuration list for PBXProject "PoissonMLS" */; 155 | compatibilityVersion = "Xcode 3.2"; 156 | developmentRegion = English; 157 | hasScannedForEncodings = 0; 158 | knownRegions = ( 159 | en, 160 | ); 161 | mainGroup = 2AA6F2091920C94E005B4AF8; 162 | productRefGroup = 2AA6F2131920C94E005B4AF8 /* Products */; 163 | projectDirPath = ""; 164 | projectRoot = ""; 165 | targets = ( 166 | 2AA6F2111920C94E005B4AF8 /* PoissonMLS */, 167 | ); 168 | }; 169 | /* End PBXProject section */ 170 | 171 | /* Begin PBXSourcesBuildPhase section */ 172 | 2AA6F20E1920C94E005B4AF8 /* Sources */ = { 173 | isa = PBXSourcesBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | 2AA6F2161920C94E005B4AF8 /* PoissonMLS.cpp in Sources */, 177 | 2AA6F2181920C94E005B4AF8 /* StdAfx.cpp in Sources */, 178 | ); 179 | runOnlyForDeploymentPostprocessing = 0; 180 | }; 181 | /* End PBXSourcesBuildPhase section */ 182 | 183 | /* Begin XCBuildConfiguration section */ 184 | 2AA6F21B1920C94E005B4AF8 /* Debug */ = { 185 | isa = XCBuildConfiguration; 186 | buildSettings = { 187 | ALWAYS_SEARCH_USER_PATHS = NO; 188 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 189 | CLANG_CXX_LIBRARY = "libc++"; 190 | CLANG_ENABLE_MODULES = YES; 191 | CLANG_ENABLE_OBJC_ARC = YES; 192 | CLANG_WARN_BOOL_CONVERSION = YES; 193 | CLANG_WARN_CONSTANT_CONVERSION = YES; 194 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 195 | CLANG_WARN_EMPTY_BODY = YES; 196 | CLANG_WARN_ENUM_CONVERSION = YES; 197 | CLANG_WARN_INFINITE_RECURSION = YES; 198 | CLANG_WARN_INT_CONVERSION = YES; 199 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 200 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 201 | CLANG_WARN_UNREACHABLE_CODE = YES; 202 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 203 | COPY_PHASE_STRIP = NO; 204 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 205 | ENABLE_STRICT_OBJC_MSGSEND = YES; 206 | ENABLE_TESTABILITY = YES; 207 | GCC_C_LANGUAGE_STANDARD = gnu99; 208 | GCC_DYNAMIC_NO_PIC = NO; 209 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 210 | GCC_NO_COMMON_BLOCKS = YES; 211 | GCC_OPTIMIZATION_LEVEL = 0; 212 | GCC_PREPROCESSOR_DEFINITIONS = ( 213 | MAC_PLUGIN, 214 | _BOOL, 215 | REQUIRE_IOSTREAM, 216 | OSMac_, 217 | DEBUG, 218 | ); 219 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 220 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 221 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 222 | GCC_WARN_UNDECLARED_SELECTOR = YES; 223 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 224 | GCC_WARN_UNUSED_FUNCTION = YES; 225 | GCC_WARN_UNUSED_VARIABLE = YES; 226 | MACOSX_DEPLOYMENT_TARGET = 10.12; 227 | ONLY_ACTIVE_ARCH = YES; 228 | SDKROOT = macosx; 229 | USER_HEADER_SEARCH_PATHS = /usr/local/include/eigen3/; 230 | }; 231 | name = Debug; 232 | }; 233 | 2AA6F21C1920C94E005B4AF8 /* Release */ = { 234 | isa = XCBuildConfiguration; 235 | buildSettings = { 236 | ALWAYS_SEARCH_USER_PATHS = NO; 237 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 238 | CLANG_CXX_LIBRARY = "libc++"; 239 | CLANG_ENABLE_MODULES = YES; 240 | CLANG_ENABLE_OBJC_ARC = YES; 241 | CLANG_WARN_BOOL_CONVERSION = YES; 242 | CLANG_WARN_CONSTANT_CONVERSION = YES; 243 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 244 | CLANG_WARN_EMPTY_BODY = YES; 245 | CLANG_WARN_ENUM_CONVERSION = YES; 246 | CLANG_WARN_INFINITE_RECURSION = YES; 247 | CLANG_WARN_INT_CONVERSION = YES; 248 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 249 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 250 | CLANG_WARN_UNREACHABLE_CODE = YES; 251 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 252 | COPY_PHASE_STRIP = YES; 253 | ENABLE_NS_ASSERTIONS = NO; 254 | ENABLE_STRICT_OBJC_MSGSEND = YES; 255 | GCC_C_LANGUAGE_STANDARD = gnu99; 256 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 257 | GCC_NO_COMMON_BLOCKS = YES; 258 | GCC_PREPROCESSOR_DEFINITIONS = ( 259 | MAC_PLUGIN, 260 | _BOOL, 261 | REQUIRE_IOSTREAM, 262 | OSMac_, 263 | ); 264 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 265 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 266 | GCC_WARN_UNDECLARED_SELECTOR = YES; 267 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 268 | GCC_WARN_UNUSED_FUNCTION = YES; 269 | GCC_WARN_UNUSED_VARIABLE = YES; 270 | MACOSX_DEPLOYMENT_TARGET = 10.12; 271 | SDKROOT = macosx; 272 | USER_HEADER_SEARCH_PATHS = /usr/local/include/eigen3/; 273 | }; 274 | name = Release; 275 | }; 276 | 2AA6F21E1920C94E005B4AF8 /* Debug */ = { 277 | isa = XCBuildConfiguration; 278 | buildSettings = { 279 | ALWAYS_SEARCH_USER_PATHS = YES; 280 | COPY_PHASE_STRIP = NO; 281 | DYLIB_COMPATIBILITY_VERSION = ""; 282 | DYLIB_CURRENT_VERSION = ""; 283 | EXECUTABLE_EXTENSION = bundle; 284 | GCC_OPTIMIZATION_LEVEL = 0; 285 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 286 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 287 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 288 | GCC_WARN_UNUSED_VARIABLE = YES; 289 | HEADER_SEARCH_PATHS = ( 290 | ., 291 | "$(MAYA_LOCATION)/devkit/include/", 292 | ); 293 | LIBRARY_SEARCH_PATHS = "$(MAYA_LOCATION)/Maya.app/Contents/MacOS"; 294 | MACH_O_TYPE = mh_bundle; 295 | MACOSX_DEPLOYMENT_TARGET = ""; 296 | MAYA_LOCATION = /Applications/Autodesk/maya; 297 | ONLY_ACTIVE_ARCH = NO; 298 | OTHER_LDFLAGS = ( 299 | "-Wl,-executable_path,$(MAYA_LOCATION)/Maya.app/Contents/MacOS", 300 | "-lOpenMaya", 301 | "-lOpenMayaAnim", 302 | "-lOpenMayaRender", 303 | "-lOpenMayaUI", 304 | "-lFoundation", 305 | ); 306 | PRODUCT_NAME = "$(TARGET_NAME)"; 307 | VALID_ARCHS = x86_64; 308 | }; 309 | name = Debug; 310 | }; 311 | 2AA6F21F1920C94E005B4AF8 /* Release */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | ALWAYS_SEARCH_USER_PATHS = YES; 315 | COPY_PHASE_STRIP = YES; 316 | DYLIB_COMPATIBILITY_VERSION = ""; 317 | DYLIB_CURRENT_VERSION = ""; 318 | EXECUTABLE_EXTENSION = bundle; 319 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 320 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 321 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 322 | GCC_WARN_UNUSED_VARIABLE = YES; 323 | HEADER_SEARCH_PATHS = ( 324 | ., 325 | "$(MAYA_LOCATION)/devkit/include/", 326 | ); 327 | LIBRARY_SEARCH_PATHS = "$(MAYA_LOCATION)/Maya.app/Contents/MacOS"; 328 | MACH_O_TYPE = mh_bundle; 329 | MACOSX_DEPLOYMENT_TARGET = ""; 330 | MAYA_LOCATION = /Applications/Autodesk/maya; 331 | ONLY_ACTIVE_ARCH = NO; 332 | OTHER_LDFLAGS = ( 333 | "-Wl,-executable_path,$(MAYA_LOCATION)/Maya.app/Contents/MacOS", 334 | "-lOpenMaya", 335 | "-lOpenMayaAnim", 336 | "-lOpenMayaRender", 337 | "-lOpenMayaUI", 338 | "-lFoundation", 339 | ); 340 | PRODUCT_NAME = "$(TARGET_NAME)"; 341 | VALID_ARCHS = x86_64; 342 | }; 343 | name = Release; 344 | }; 345 | /* End XCBuildConfiguration section */ 346 | 347 | /* Begin XCConfigurationList section */ 348 | 2AA6F20D1920C94E005B4AF8 /* Build configuration list for PBXProject "PoissonMLS" */ = { 349 | isa = XCConfigurationList; 350 | buildConfigurations = ( 351 | 2AA6F21B1920C94E005B4AF8 /* Debug */, 352 | 2AA6F21C1920C94E005B4AF8 /* Release */, 353 | ); 354 | defaultConfigurationIsVisible = 0; 355 | defaultConfigurationName = Release; 356 | }; 357 | 2AA6F21D1920C94E005B4AF8 /* Build configuration list for PBXNativeTarget "PoissonMLS" */ = { 358 | isa = XCConfigurationList; 359 | buildConfigurations = ( 360 | 2AA6F21E1920C94E005B4AF8 /* Debug */, 361 | 2AA6F21F1920C94E005B4AF8 /* Release */, 362 | ); 363 | defaultConfigurationIsVisible = 0; 364 | defaultConfigurationName = Release; 365 | }; 366 | /* End XCConfigurationList section */ 367 | }; 368 | rootObject = 2AA6F20A1920C94E005B4AF8 /* Project object */; 369 | } 370 | -------------------------------------------------------------------------------- /mayaHeaders.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2012 Autodesk, Inc. All rights reserved. 3 | // 4 | // Use of this software is subject to the terms of the Autodesk license 5 | // agreement provided at the time of installation or download, or which 6 | // otherwise accompanies this software in either electronic or hard copy form. 7 | // 8 | 9 | //- Written by Cyrille Fauvel, Autodesk Developer Network (ADN) 10 | //- http://www.autodesk.com/joinadn 11 | 12 | //----------------------------------------------------------------------------- 13 | #pragma once 14 | 15 | #if defined(_MANAGED) 16 | #pragma unmanaged 17 | #pragma message(__FILE__ " Turning down managed code") 18 | #endif 19 | 20 | #if defined(_MANAGED) && !defined(MNoMSTypedef) 21 | //- The MS typedef can cause errors when linking with .NET libraries on Windows. 22 | //- Use the MNoMSTypedef define to force all status codes to be prefixed by MStatus:: instead of MS::. 23 | #define MNoMSTypedef 24 | #pragma message(__FILE__ " Turning MNoMSTypedef on - MS typedef can cause errors when linking with .NET libraries on Windows.") 25 | #endif 26 | 27 | //----------------------------------------------------------------------------- 28 | #if defined(NT_PLUGIN) && !defined(_MANAGED) 29 | #define EXPORT comment(linker, "/EXPORT:"__FUNCTION__"="__FUNCDNAME__) 30 | #else 31 | #define EXPORT 32 | #endif 33 | 34 | //----------------------------------------------------------------------------- 35 | #define MayaOk(a,b) \ 36 | if ( !a ) { \ 37 | a.perror (b) ; \ 38 | return (a) ; \ 39 | } 40 | #define NodeRegisterOk(a) MayaOk(a,_T("registerNode")) 41 | #define NodeUnregisterOk(a) MayaOk(a,_T("deregisterNode")) 42 | 43 | //----------------------------------------------------------------------------- 44 | //----- This file is preprocessor symbol driven. 45 | //----- Define: 46 | //----- _PYTHON_MODULE_ to include and import Python headers and libs in your project. 47 | //----- _MAYA_QT_ to include and import Maya QT headers and libs in your project. 48 | //----- _MAYA_VP2_ to include and import Maya Viewport 2.0 headers and libs in your project. 49 | 50 | //----------------------------------------------------------------------------- 51 | #ifdef NT_PLUGIN 52 | #pragma comment (lib, "cg.lib") 53 | #pragma comment (lib, "cgGL.lib") 54 | #pragma comment (lib, "Foundation.lib") 55 | #pragma comment (lib, "Image.lib") 56 | #pragma comment (lib, "IMFbase.lib") 57 | #pragma comment (lib, "awxml2.lib") 58 | #pragma comment (lib, "libmocap.lib") 59 | #pragma comment (lib, "zlib.lib") 60 | #pragma comment (lib, "OpenMaya.lib") 61 | #pragma comment (lib, "OpenMayaAnim.lib") 62 | #pragma comment (lib, "OpenMayaFX.lib") 63 | #pragma comment (lib, "OpenMayaRender.lib") 64 | #pragma comment (lib, "OpenMayaUI.lib") 65 | #pragma comment (lib, "tbb.lib") 66 | #pragma comment (lib, "tbbmalloc.lib") 67 | #endif 68 | 69 | //----------------------------------------------------------------------------- 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include 78 | #include 79 | #include 80 | #include 81 | #include 82 | #include 83 | //#include 84 | #include 85 | #include 86 | #include 87 | #include 88 | #include 89 | #include 90 | #include 91 | #include 92 | #include 93 | #include 94 | #include 95 | #include 96 | #include 97 | #include 98 | #include 99 | #include 100 | #include 101 | #include 102 | #include 103 | #include 104 | #include 105 | #include 106 | #include 107 | #include 108 | #include 109 | #include 110 | #include 111 | #include 112 | #include 113 | #include 114 | #include 115 | #include 116 | #include 117 | #include 118 | #include 119 | #include 120 | #include 121 | #include 122 | #include 123 | #include 124 | #include 125 | #include 126 | #include 127 | #include 128 | #include 129 | #include 130 | #include 131 | #include 132 | #include 133 | #include 134 | #include 135 | #include 136 | #include 137 | #include 138 | #include 139 | #include 140 | #include 141 | #include 142 | #include 143 | #include 144 | #include 145 | #include 146 | #include 147 | #include 148 | #include 149 | #include 150 | #include 151 | #include 152 | #include 153 | #include 154 | #include 155 | #include 156 | #include 157 | #include 158 | #include 159 | #include 160 | #include 161 | #include 162 | #include 163 | #include 164 | #include 165 | #include 166 | #include 167 | #include 168 | #include 169 | #include 170 | #include 171 | #include 172 | #include 173 | #include 174 | #include 175 | #include 176 | #include 177 | #include 178 | #include 179 | #include 180 | #include 181 | #include 182 | #include 183 | #include 184 | #include 185 | #include 186 | #include 187 | #include 188 | #include 189 | #include 190 | #include 191 | #include 192 | #include 193 | #include 194 | #include 195 | #include 196 | #include 197 | #include 198 | #include 199 | #include 200 | #include 201 | #include 202 | #include 203 | #include 204 | #include 205 | #include 206 | #include 207 | #include 208 | #include 209 | #include 210 | #include 211 | #include 212 | #include 213 | #include 214 | #include 215 | #include 216 | #include 217 | #include 218 | #include 219 | #include 220 | #include 221 | #include 222 | #include 223 | #include 224 | #include 225 | //#include 226 | #include 227 | #include 228 | #include 229 | #include 230 | #include 231 | #include 232 | #include 233 | #include 234 | #include 235 | #include 236 | #include 237 | #include 238 | #include 239 | #include 240 | #include 241 | #include 242 | #include 243 | #include 244 | #include 245 | #include 246 | #include 247 | #include 248 | #include 249 | #include 250 | #include 251 | #include 252 | #include 253 | #include 254 | #include 255 | #include 256 | #include 257 | #include 258 | #include 259 | #include 260 | #include 261 | #include 262 | #include 263 | #include 264 | #include 265 | #include 266 | #include 267 | #include 268 | #include 269 | #include 270 | #include 271 | #include 272 | #include 273 | #include 274 | #include 275 | #include 276 | #include 277 | #include 278 | #include 279 | #include 280 | #include 281 | #include 282 | #include 283 | #include 284 | #include 285 | #include 286 | #include 287 | #include 288 | #include 289 | #include 290 | #include 291 | #include 292 | #include 293 | #include 294 | #include 295 | #include 296 | #include 297 | #include 298 | #include 299 | #include 300 | #include 301 | #include 302 | #include 303 | #include 304 | //#include 305 | #include 306 | #include 307 | #include 308 | #include 309 | #include 310 | #include 311 | #include 312 | #include 313 | #include 314 | #include 315 | #include 316 | #include 317 | #include 318 | #include 319 | #include 320 | #include 321 | #include 322 | #include 323 | #include 324 | #include 325 | #include 326 | #include 327 | #include 328 | #include 329 | #include 330 | #include 331 | #include 332 | #include 333 | #include 334 | #include 335 | #include 336 | #include 337 | #include 338 | #include 339 | #include 340 | #include 341 | #include 342 | #include 343 | #include 344 | #include 345 | #include 346 | #include 347 | //#include 348 | #include 349 | #include 350 | #include 351 | #include 352 | #include 353 | #include 354 | #include 355 | #include 356 | #include 357 | #include 358 | #include 359 | #include 360 | #include 361 | #include 362 | #include 363 | #include 364 | #include 365 | #include 366 | #include 367 | #include 368 | #include 369 | #include 370 | #include 371 | #include 372 | #include 373 | #include 374 | #include 375 | #include 376 | #include 377 | #include 378 | #include 379 | #include 380 | #include 381 | #include 382 | #include 383 | #include 384 | #include 385 | #include 386 | #include 387 | #include 388 | #include 389 | #include 390 | #include 391 | #include 392 | #include 393 | #include 394 | #include 395 | #include 396 | #include 397 | #include 398 | #include 399 | #include 400 | #include 401 | //#include 402 | #include 403 | #include 404 | #include 405 | #include 406 | #include 407 | #include 408 | #include 409 | #include 410 | #include 411 | #include 412 | //#include 413 | //#include 414 | #include 415 | #include 416 | #include 417 | #include 418 | #include 419 | #include 420 | #include 421 | #include 422 | #include 423 | #include 424 | #include 425 | #include 426 | #include 427 | #include 428 | #include 429 | #include 430 | #include 431 | #include 432 | #include 433 | #include 434 | #include 435 | #include 436 | #include 437 | #include 438 | 439 | #ifdef _MAYA_VP2_ 440 | // Viewport 2.0 includes 441 | #include 442 | #include 443 | #include 444 | #include 445 | #include 446 | #include 447 | #endif 448 | 449 | #ifdef _PYTHON_MODULE_ 450 | #include 451 | #include 452 | #include 453 | #include 454 | #include 455 | #include 456 | #include 457 | #include 458 | #include 459 | #include 460 | #include 461 | #include 462 | #include 463 | #include 464 | #include 465 | #include 466 | #include 467 | #include 468 | #include 469 | #include 470 | #include 471 | #include 472 | #include 473 | #include 474 | #include 475 | #include 476 | #include 477 | #include 478 | #include 479 | #include 480 | #include 481 | #include 482 | #include 483 | #include 484 | #include 485 | #include 486 | #include 487 | #include 488 | #include 489 | #include 490 | #include 491 | #include 492 | #include 493 | #include 494 | #include 495 | #include 496 | #include 497 | #include 498 | #include 499 | #include 500 | #include 501 | #include 502 | #include 503 | #include 504 | #include 505 | #include 506 | #include 507 | #include 508 | #include 509 | #include 510 | #include 511 | #include 512 | #include 513 | #include 514 | #include 515 | #include 516 | #include 517 | #include 518 | #include 519 | #include 520 | #include 521 | #include 522 | #include 523 | #include 524 | #include 525 | #include 526 | #include 527 | #include 528 | #include 529 | #include 530 | #include 531 | #include 532 | #include 533 | #include 534 | #include 535 | #include 536 | #include 537 | #include 538 | #endif 539 | 540 | #if defined(_MANAGED) 541 | #pragma managed 542 | #pragma message(__FILE__ " Turning managed code back on") 543 | #endif 544 | -------------------------------------------------------------------------------- /tetrise.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file tetrise.h 3 | * @brief tet-rise surface mesh 4 | * @section LICENSE The MIT License 5 | * @section requirements: Eigen library, (optional) MKL 6 | * @version 0.10 7 | * @date Jul. 2014 8 | * @author Shizuo KAJI 9 | */ 10 | 11 | 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "deformerConst.h" 25 | 26 | 27 | using namespace Eigen; 28 | 29 | // class for a pair of numerics 30 | template 31 | class couple{ 32 | public: 33 | T left, right; 34 | couple() {}; 35 | couple(T l, T r){ 36 | left = l; 37 | right = r; 38 | } 39 | bool operator==(const couple& pa){ 40 | return (left == pa.left && right == pa.right); 41 | } 42 | bool operator<(const couple& pa) const { 43 | return ( left vertices; 51 | std::vector faces; 52 | edge(){ 53 | vertices.resize(2); 54 | faces.resize(2); 55 | } 56 | edge(int s,int t,int f,int g){ 57 | vertices.resize(2); 58 | faces.resize(2); 59 | vertices[0]=s; // vertex index of Maya 60 | vertices[1]=t; 61 | faces[0]=f; // adjacent face index of faceList 62 | faces[1]=g; 63 | } 64 | edge &operator=(const edge &e){ 65 | vertices[0]=e.vertices[0]; 66 | vertices[1]=e.vertices[1]; 67 | faces[0]=e.faces[0]; 68 | faces[1]=e.faces[1]; 69 | return(*this); 70 | } 71 | }; 72 | 73 | // vertex data 74 | class vertex{ 75 | public: 76 | int index; // vertex index of Maya 77 | std::vector connectedTriangles; // list of vertex indices. sorted in such a way that index-1-2, index-3-4,..., index-(last-1)-last form oriented faces 78 | vertex(){ 79 | connectedTriangles.clear(); 80 | } 81 | vertex(int idx, std::vector list){ 82 | index = idx; 83 | connectedTriangles=list; 84 | } 85 | vertex &operator=(const vertex &v){ 86 | index = v.index; 87 | connectedTriangles=v.connectedTriangles; 88 | return(*this); 89 | } 90 | }; 91 | 92 | 93 | 94 | /// 95 | namespace Tetrise{ 96 | // compose a matrix out of four vectors 97 | Matrix4d mat(Vector3d p0,Vector3d p1,Vector3d p2,Vector3d c){ 98 | Matrix4d m; 99 | m << p0[0], p0[1], p0[2], 1, 100 | p1[0], p1[1], p1[2], 1, 101 | p2[0], p2[1], p2[2], 1, 102 | c[0], c[1], c[2], 1; 103 | return m; 104 | } 105 | 106 | // make the list of (inner) edges 107 | int makeEdgeList(const std::vector& faceList, std::vector& edgeList){ 108 | edgeList.clear(); 109 | edgeList.reserve(faceList.size()); 110 | std::map< couple, int > edges; 111 | int s,t; 112 | for(int i=0;it) swap(s,t); 117 | couple pa(s,t); 118 | if( edges.find(pa) == edges.end() ){ // if not in the list 119 | edges[pa] = i; 120 | }else{ 121 | edge newEdge(s,t,edges[pa],i); 122 | edgeList.push_back(newEdge); 123 | } 124 | } 125 | } 126 | return (int)edgeList.size(); 127 | } 128 | 129 | // make the list of tetrahedra 130 | int makeTetList(short tetMode, int numPts, const std::vector& faceList, 131 | const std::vector& edgeList, const std::vector& vertexList, 132 | std::vector& tetList){ 133 | tetList.clear(); 134 | int dim=0; // number of total points including ghost ones 135 | if(tetMode == TM_FACE){ 136 | int numTet = (int)faceList.size()/3; 137 | dim = numTet + numPts; 138 | tetList.resize(4*numTet); 139 | for(int i=0;i& tetList, 194 | const std::vector& faceList, const std::vector& edgeList, 195 | const std::vector& vertexList, const VectorXd& ptsWeight, 196 | std::vector& tetWeight ){ 197 | int numTet = (int)tetList.size()/4; 198 | tetWeight.resize(numTet); 199 | if(tetMode == TM_FACE){ 200 | for(int i=0;i& tetList, 217 | const std::vector& faceList, const std::vector& edgeList, 218 | const std::vector& vertexList, const std::vector& tetWeight, 219 | std::vector& ptsWeight ){ 220 | int numTet = (int)tetList.size()/4; 221 | ptsWeight.clear(); 222 | ptsWeight.resize(numPts,0.0); 223 | std::vector ptsCount(numPts,0); 224 | if(tetMode == TM_FACE){ 225 | for(int i=0;i& pts, const std::vector& tetList, 253 | const std::vector& faceList, const std::vector& edgeList, 254 | const std::vector& vertexList, std::vector& P, std::vector& tetWeight, bool normalise=false){ 255 | Vector3d u, v, q, c; 256 | int numTet = (int)tetList.size()/4; 257 | P.clear(); 258 | P.reserve(numTet); 259 | tetWeight.clear(); 260 | tetWeight.reserve(numTet); 261 | if(tetMode == TM_FACE){ 262 | for(int i=0;i& tetList, 348 | const std::vector& edgeList, const std::vector& vertexList, 349 | std::vector< std::vector >& adjacencyList){ 350 | adjacencyList.resize(tetList.size()/4); 351 | for(int i=0;i > faceShareList(2*edgeList.size()); 361 | for(int i=0;i<2*edgeList.size();i++){ 362 | faceShareList[i].clear(); 363 | } 364 | for(int i=0;i, int > edges; 380 | int s,t,cur=0; 381 | for(int i=0;i adj(vertexList[i].connectedTriangles.size()/2); 383 | for(int j=0;j pa1(vertexList[i].index,s),pa2(t,vertexList[i].index); 392 | if( edges.find(pa1) == edges.end() ){ // if not in the list 393 | edges[pa1] = cur; 394 | }else{ 395 | adjacencyList[cur].push_back(edges[pa1]); 396 | adjacencyList[edges[pa1]].push_back(cur); 397 | } 398 | if( edges.find(pa2) == edges.end() ){ // if not in the list 399 | edges[pa2] = cur; 400 | }else{ 401 | adjacencyList[cur].push_back(edges[pa2]); 402 | adjacencyList[edges[pa2]].push_back(cur); 403 | } 404 | cur++; 405 | } 406 | } 407 | } 408 | } 409 | 410 | // get rid of degenerate tetrahedra 411 | int removeDegenerate(short tetMode, int numPts, 412 | std::vector& tetList, std::vector& faceList, std::vector& edgeList, 413 | std::vector& vertexList, const std::vector& P){ 414 | if (tetMode == TM_FACE){ 415 | std::vector goodList(0); 416 | std::vector oldFaceList = faceList; 417 | int numTet = (int)tetList.size()/4; 418 | for(int i=0;iEPSILON){ 420 | goodList.push_back(i); 421 | } 422 | } 423 | int numFaces = (int)goodList.size(); 424 | faceList.resize(3*numFaces); 425 | for(int i=0;i oldEdgeList(edgeList.size()); 434 | std::copy(edgeList.begin(), edgeList.end(), oldEdgeList.begin() ); 435 | // enumerate good edges 436 | std::vector goodList(0); 437 | int numEdges = (int)edgeList.size(); 438 | for(int i=0;iEPSILON && abs(P[2*i+1].determinant())>EPSILON){ 440 | goodList.push_back(i); 441 | } 442 | } 443 | numEdges = (int)goodList.size(); 444 | edgeList.resize(numEdges); 445 | for(int i=0;i oldVertexList(vertexList.size()); 451 | std::copy(vertexList.begin(), vertexList.end(), oldVertexList.begin()); 452 | // enumerate good edges 453 | std::vector goodList(0); 454 | int cur = 0; 455 | for(int i=0;iEPSILON; 459 | cur++; 460 | } 461 | if(isGood) goodList.push_back(i); 462 | } 463 | vertexList.resize(goodList.size()); 464 | for(int i=0;i& pts, 473 | const std::vector& tetList, 474 | std::vector& tetCenter ){ 475 | int numTet = (int)tetList.size()/4; 476 | tetCenter.resize(numTet); 477 | if(tetMode == TM_FACE ){ 478 | for(int i=0;i 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | // disable assert lines 34 | #define NDEBUG 35 | #include 36 | 37 | /// threshold for small values to be regarded zero 38 | #define EPSILON 10e-15 39 | // for assert() 40 | #define TOLERANCE 10e-5 41 | 42 | /// 3x3 identity matrix 43 | #define Id3 Matrix3d::Identity() 44 | /// macro to print an Eigen object 45 | #define PRINT_MAT(X) std::cout << #X << ":\n" << X << std::endl << std::endl 46 | 47 | // 48 | using namespace Eigen; 49 | using namespace std; 50 | /// For vecterization of Eigen objects 51 | EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Matrix4d); 52 | EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Vector4d); 53 | 54 | // main body 55 | namespace AffineLib{ 56 | Matrix4d pad(const Matrix3d& m, const Vector3d& l, const double br=1.0) 57 | /** compose an affine matrix from linear matrix and translation vector 58 | * @param m 3x3-matrix 59 | * @param l 3-dim translation vector 60 | * @param br value of bottom right corner; set to 0.0 for log matrix 61 | * @return 4x4-affine transformation matrix 62 | */ 63 | { 64 | Matrix4d aff; 65 | aff << m(0,0),m(0,1),m(0,2),0.0, 66 | m(1,0),m(1,1),m(1,2),0.0, 67 | m(2,0),m(2,1),m(2,2),0.0, 68 | l[0],l[1],l[2],br; 69 | return aff; 70 | } 71 | 72 | RowVector4d pad(const Vector3d& v) 73 | /** compose a 4-vector by concatenating 1 at the 4th coordinate 74 | * @param v 3-vector 75 | * @return 4-vector 76 | */ 77 | { 78 | return RowVector4d(v[0],v[1],v[2],1); 79 | } 80 | 81 | Vector3d transPart(const Matrix4d& m){ 82 | /** extract the translation vector from an affine matrix 83 | * @param m affine matrix 84 | * @return 3D translation vector 85 | */ 86 | return Vector3d(m(3,0),m(3,1),m(3,2)); 87 | } 88 | 89 | Matrix3d logSO(const Matrix3d& m) 90 | /** Log for a rotational matrix using Axis-Angle 91 | * @param m rotational matrix 92 | * @return primary value of log(m) 93 | */ 94 | { 95 | assert( (m*m.transpose()-Id3).squaredNorm() < TOLERANCE ); 96 | AngleAxisd X(m); 97 | Matrix3d A; 98 | A << 0, -X.axis()[2], X.axis()[1], 99 | X.axis()[2], 0, -X.axis()[0], 100 | -X.axis()[1], X.axis()[0], 0; 101 | return X.angle() * A; 102 | } 103 | 104 | Matrix3d logSOc(const Matrix3d& m, const Matrix3d& P = Matrix3d::Zero()) 105 | /** "Continuous" log for a rotational matrix 106 | * @param m rotational matrix 107 | * @param P anti-symmetric matrix 108 | * @return the branch of log(m) closest to P 109 | */ 110 | { 111 | assert( (m*m.transpose()-Id3).squaredNorm() < TOLERANCE ); 112 | AngleAxisd X(m); 113 | Matrix3d A; 114 | double theta=X.angle(); 115 | Vector3d n=X.axis(); 116 | Vector3d prevN(-P(1,2),P(0,2),-P(0,1)); 117 | double prevTheta=prevN.norm(); 118 | if(abs(sin(theta))==0.0){ 119 | n=prevN; 120 | } 121 | A << 0, -n[2], n[1], 122 | n[2], 0, -n[0], 123 | -n[1], n[0], 0; 124 | if(n.dot(prevN)<0){ 125 | A = -A; 126 | theta = -theta; 127 | } 128 | while(theta-prevTheta>M_PI){ 129 | theta -= 2*M_PI; 130 | } 131 | while(prevTheta-theta>M_PI){ 132 | theta += 2*M_PI; 133 | } 134 | return(theta*A); 135 | } 136 | 137 | Matrix3d expTaylor(const Matrix3d& m, const int deg = 50) 138 | /** exp by Taylor expansion 139 | * @param m 3x3 matrix 140 | * @param deg degree of Taylor expansion 141 | * @return exp(m) 142 | */ 143 | { 144 | Matrix3d A = Id3; 145 | Matrix3d mPow = Id3; 146 | for(int i=1;i 0 && s[1] > 0 && s[2] > 0); 248 | Vector3d d = s.array().log(); 249 | return(U* d.asDiagonal() *U.transpose()); 250 | } 251 | 252 | Matrix3d expDiag(const Matrix3d& U, const Vector3d& s) 253 | /** exp for a diagonalised matrix m = U diag(s) U^{-1} 254 | * @param U diagonalising matrix 255 | * @param s eigenvalues 256 | * @return exp(m) 257 | */ 258 | { 259 | Vector3d d = s.array().exp(); 260 | return(U* d.asDiagonal() *U.inverse()); 261 | } 262 | 263 | Matrix3d expSymDiag(const Matrix3d& m) 264 | /** exp for a symmetric matrix by diagonalization 265 | * @param m symmetric matrix 266 | * @return exp(m) 267 | */ 268 | { 269 | assert( ((m - m.transpose())).squaredNorm() < TOLERANCE ); 270 | if (m.squaredNorm() < EPSILON){ 271 | return Id3+m+0.5*m*m; 272 | } 273 | SelfAdjointEigenSolver eigensolver; 274 | eigensolver.compute(m); 275 | Vector3d s(eigensolver.eigenvalues()); 276 | Matrix3d U(eigensolver.eigenvectors()); 277 | s = s.array().exp(); 278 | return(U * s.asDiagonal() * U.transpose()); 279 | } 280 | 281 | Matrix3d logSymDiag(const Matrix3d& m) 282 | /** log for a symmetric matrix by diagonalization 283 | * @param m symmetric matrix 284 | * @return log(m) 285 | */ 286 | { 287 | assert( ((m - m.transpose())).squaredNorm() < TOLERANCE ); 288 | if ((m-Id3).squaredNorm() < EPSILON){ 289 | return m-Id3-0.5*(m-Id3)*(m-Id3); 290 | } 291 | SelfAdjointEigenSolver eigensolver; 292 | eigensolver.compute(m); 293 | Vector3d s(eigensolver.eigenvalues()); 294 | Matrix3d U(eigensolver.eigenvectors()); 295 | s = s.array().log(); 296 | return(U * s.asDiagonal() * U.transpose()); 297 | } 298 | 299 | Matrix3d expSym(const Matrix3d& m, Vector3d e=Vector3d::Zero()) 300 | /** exp for a symmetric matrix by spectral decomposition 301 | * @param m symmetric matrix 302 | * @param e if eigenvalues of m are provided, we use it 303 | * @return exp(m) 304 | */ 305 | { 306 | assert( ((m - m.transpose())).squaredNorm() < TOLERANCE ); 307 | if(e == Vector3d::Zero()){ 308 | // compute eigenvalues if not given 309 | // eigenvalues are sorted in increasing order. 310 | SelfAdjointEigenSolver eigensolver; 311 | eigensolver.computeDirect(m, EigenvaluesOnly); 312 | e = eigensolver.eigenvalues(); 313 | if(abs(e[0])EPSILON ? (exp(x)-1-x)/(x*x) : 0.5+x/6+x*x/24; 324 | double t2ey = abs(y)>EPSILON ? (exp(y)-1-y)/(y*y) : 0.5+y/6+y*y/24; 325 | 326 | double b = 1- x*y*(t2ex-t2ey)/(x-y); 327 | double c = (x*t2ex- y*t2ey)/(x-y); 328 | Matrix3d ans(exp(e[1])*( Id3 + b*A + c*A*A)); 329 | return (ans+ans.transpose())/2; 330 | } 331 | 332 | 333 | Matrix3d logSym(const Matrix3d& m, Vector3d& lambda) 334 | /** log for a positive definite symmetric matrix by spectral decomposition 335 | * @param m symmetric matrix 336 | * @param lambda returns eigen values for log(m) 337 | * @return log(m) 338 | */ 339 | { 340 | assert( ((m - m.transpose())).squaredNorm() < TOLERANCE ); 341 | // compute eigenvalues only 342 | // eigenvalues are sorted in the increasing order. 343 | SelfAdjointEigenSolver eigensolver; 344 | eigensolver.computeDirect(m, EigenvaluesOnly); 345 | Vector3d e(eigensolver.eigenvalues()); 346 | if(abs(e[0]) 0 && e[1] > 0 && e[2] > 0); 351 | lambda = e.array().log(); 352 | double x(e[0]/e[1]),y(e[2]/e[1]); 353 | double t2lx = abs(x-1)>EPSILON ? (log(x)-x+1)/(x-1) : -(x-1)/2+(x-1)*(x-1)/3; 354 | double t2ly = abs(y-1)>EPSILON ? (log(y)-y+1)/(y-1) : -(y-1)/2+(y-1)*(y-1)/3; 355 | double a,c; 356 | if(abs(x-y)>EPSILON){ 357 | a = -1 + (y*t2lx - x*t2ly)/(x-y); 358 | c = (t2lx - t2ly)/(x-y); 359 | }else{ 360 | a = -1/6 + x*y/3; 361 | c = -0.5 + (x+y)/3; 362 | } 363 | Matrix3d ans((a+log(e[1]))*Id3 - (a+c)/e[1]*m + c/(e[1]*e[1])*m*m); 364 | return (ans+ans.transpose())/2; 365 | } 366 | 367 | 368 | Matrix3d frechetSO(const std::vector &m, const std::vector &w, const int max_step=10) 369 | /** the Frechet mean for rotations 370 | * @param m array of rotation matrices to be averaged 371 | * @param w array of weights 372 | * @param max_step max steps for iteration 373 | * @return weighted Frechet mean 374 | */ 375 | { 376 | assert(m.size() == w.size()); 377 | if(m.empty()) return(Id3); 378 | Matrix3d Z = m[0]; 379 | for(int i=0;i &m, const std::vector &w, const int max_step=10) 394 | /** the Frechet mean for symmetric matrices 395 | * @param m array of positive definite symmetric matrices to be averaged 396 | * @param w array of weights 397 | * @param max_step max steps for iteration 398 | * @return weighted Frechet mean 399 | */ 400 | { 401 | assert(m.size() == w.size()); 402 | if(m.empty()) return(Id3); 403 | Vector3d e; 404 | Matrix3d Z = m[0]; 405 | for(int i=0;i0); 427 | Matrix3d A= m*m.transpose(); 428 | SelfAdjointEigenSolver eigensolver; 429 | eigensolver.computeDirect(A); 430 | s = eigensolver.eigenvalues(); 431 | U = Matrix3d(eigensolver.eigenvectors()); 432 | s = s.array().sqrt(); 433 | Vector3d si = s.array().inverse(); 434 | R = U * si.asDiagonal() * U.transpose() * m; 435 | } 436 | 437 | void polarN(const MatrixXf& m, MatrixXf& S, MatrixXf& R) 438 | /** Polar decomposition m = S R for square matrix of any size 439 | * @param m matrix to be decomposed 440 | * @param S symmetric part 441 | * @param R rotation part 442 | */ 443 | { 444 | assert(m.determinant()>0); 445 | MatrixXf A= m*m.transpose(); 446 | long N = A.rows(); 447 | SelfAdjointEigenSolver eigensolver; 448 | eigensolver.compute(A, EigenvaluesOnly); 449 | VectorXf s = eigensolver.eigenvalues(); 450 | MatrixXf VM = MatrixXf::Zero(N,N); 451 | double ss; 452 | for(int i=0;i svd(m, ComputeFullU | ComputeFullV); 515 | U = svd.matrixU(); 516 | s = svd.singularValues(); 517 | R = svd.matrixU() * svd.matrixV().transpose(); 518 | } 519 | 520 | void polarByParam(const Matrix3d& m, Matrix3d& S, Matrix3d& R){ 521 | /** Polar decomposition m = S R by parametrisation map 522 | * @param m matrix to be decomposed 523 | * @param S shear part 524 | * @param R rotation part 525 | */ 526 | Vector3d lambda=Vector3d::Zero().eval(); 527 | Matrix3d logS = logSym(m*m.transpose(), lambda)/2.0; 528 | S = expSym(logS, lambda/2.0); 529 | R = expSym(-logS, -lambda/2.0) * m; 530 | } 531 | 532 | int polarHigham(const Matrix3d& m, Matrix3d& S, Matrix3d& R){ 533 | /** Polar decomposition m = S R by Higham's iterative method 534 | * @param m matrix to be decomposed 535 | * @param S shear part 536 | * @param R rotation part 537 | * @return number of iterations 538 | */ 539 | Matrix3d Curr = m; 540 | Matrix3d Prev; 541 | int iter=0; 542 | do { 543 | assert(Curr.determinant() != 0.0); 544 | Matrix3d Ad = Curr.inverse().transpose(); 545 | double nad = Ad.array().abs().colwise().sum().maxCoeff() * Ad.array().abs().rowwise().sum().maxCoeff(); 546 | double na = Curr.array().abs().colwise().sum().maxCoeff() * Curr.array().abs().rowwise().sum().maxCoeff(); 547 | double gamma = sqrt(sqrt(nad / na)); 548 | // std::cout << gamma << std::endl; 549 | Prev = Curr; 550 | Curr = (0.5*gamma)*Curr + (0.5/gamma) *Ad; 551 | iter++; 552 | } while ((Prev-Curr).lpNorm<1>() > EPSILON*Prev.lpNorm<1>()); 553 | R = Curr; 554 | S = m * Curr.transpose(); 555 | S = (S+S.transpose())/2; 556 | return iter; 557 | } 558 | 559 | 560 | void parametriseGL(const Matrix3d& m, Matrix3d& logS, Matrix3d& R) 561 | /** Parametrisation map for GL(3) 562 | * @param m linear matrix to be decomposed 563 | * @param logS log of shear part 564 | * @param R rotation part 565 | */ 566 | { 567 | assert(m.determinant()>0); 568 | Vector3d lambda=Vector3d::Zero(); 569 | logS = logSym(m*m.transpose(), lambda)/2.0; 570 | R = expSym(-logS, -lambda/2.0) * m; 571 | } 572 | 573 | template 574 | T blendMat(const std::vector& A, const std::vector& weight){ 575 | /** blend matrices 576 | * @param A array of matrices 577 | * @param weight array of weights 578 | * @return blended matrix 579 | */ 580 | assert(A.size() == weight.size()); 581 | T X=T::Zero(); 582 | for(int i=0;i 589 | T blendMatLin(const std::vector& A, const std::vector& weight){ 590 | /** blend matrices; if weight doesn't sum up to one, the result will be complimented by identity 591 | * this is suitable for linear blending 592 | * @param A list of matrices 593 | * @param weight list of weights 594 | * @return blended matrix 595 | */ 596 | assert(A.size() == weight.size()); 597 | T X=T::Zero(); 598 | double sum = 0.0; 599 | for(int i=0;i& A, const std::vector& weight){ 608 | /** blend 4-vector (quaternion); if weight doesn't sum up to one, the result will be complimented by 1 609 | * this is suitable for linear blending of quaternions 610 | * @param A list of 4-vectors 611 | * @param weight list of weights 612 | * @return blended 4-vector 613 | */ 614 | assert(A.size() == weight.size()); 615 | Vector4d I(0,0,0,1); 616 | Vector4d X=Vector4d::Zero(); 617 | double sum = 0.0; 618 | for(int i=0;i hInitCtlPoints.elementCount() || hCtlPoints.elementCount() == 0 || MLSMode == MLS_OFF){ 59 | return MS::kSuccess; 60 | }else if(hCtlPoints.elementCount() < hInitCtlPoints.elementCount()){ 61 | std::set indices; 62 | for(int i=0;i initCtlPoints(numPrb), ctlPoints(numPrb); 77 | readVectorArray(hInitCtlPoints, initCtlPoints); 78 | readVectorArray(hCtlPoints, ctlPoints); 79 | 80 | // load target mesh pts 81 | MPointArray Mpts; 82 | itGeo.allPositions(Mpts); 83 | int numPts = Mpts.length(); 84 | std::vector pts(numPts); 85 | for(int j=0; j ctlWeight; 118 | ctlWeight.assign(numPrb,1.0); 119 | MArrayDataHandle handle = data.inputArrayValue(aCtlWeight); 120 | if(handle.elementCount() != numPrb){ 121 | MGlobal::displayInfo("# of ctlPts and ctlWeight are different"); 122 | return MS::kFailure; 123 | } 124 | for(int i=0;i > dist; 137 | if(poisson){ 138 | dist = D.distTet; 139 | if(recompARAP){ 140 | // find constraint points 141 | double constraintWeight = data.inputValue( aConstraintWeight ).asDouble(); 142 | constraint.resize(numPrb); 143 | for(int i=0;i0) return MS::kFailure; 166 | status = data.setClean(aRecompARAP); 167 | } 168 | }else{ 169 | dist = D.distPts; 170 | } 171 | 172 | w.resize(num); 173 | for(int j=0;j effectRadius) 187 | ? EPSILON : ctlWeight[i]*pow((effectRadius-dist[i][j])/effectRadius,normExponent); 188 | } 189 | } 190 | }else if(weightMode & WM_HARMONIC){ 191 | Laplacian harmonicWeighting; 192 | makeFaceTet(data, input, inputGeom, mIndex, pts, harmonicWeighting.tetList, harmonicWeighting.tetMatrix, harmonicWeighting.tetWeight); 193 | harmonicWeighting.numTet = (int)harmonicWeighting.tetList.size()/4; 194 | std::vector weightConstraint(numPrb); 195 | // the vertex closest to the probe is given probeWeight 196 | for(int i=0;i0) return MS::kFailure; 226 | harmonicWeighting.harmonicSolve(); 227 | if(poisson){ 228 | std::vector< std::vector > w_tet(numPrb); 229 | for(int i=0;i A(num); 285 | for(int j=0; j svd(p[j]*q.transpose(), ComputeFullU | ComputeFullV); 297 | M = PPI[j] * (p[j]*q.transpose()); 298 | Matrix3d sgn = Matrix3d::Identity(); 299 | if(M.determinant()<0 && (MLSMode & MLS_POSITIVE_DET)){ 300 | sgn(2,2) = -1; 301 | } 302 | if(MLSMode & MLS_SIM){ 303 | M = svd.matrixU() * sgn * svd.matrixV().transpose(); 304 | M *= svd.singularValues().sum()/trPP[j]; 305 | }else if(MLSMode & MLS_RIGID){ 306 | M = svd.matrixU() * sgn * svd.matrixV().transpose(); 307 | } 308 | A[j] = pad(M, center-icenter[j]); 309 | } 310 | if(poisson){ 311 | // set constraint 312 | int numConstraints = constraint.size(); 313 | mesh.constraintVal.resize(numConstraints,3); 314 | RowVector3d cv; 315 | for(int cur=0;cur dummy_weight; 335 | makeTetMatrix(tetMode, pts, mesh.tetList, faceList, edgeList, vertexList, Q, dummy_weight); 336 | Matrix3d S,R,newS,newR; 337 | for(int i=0;i