├── .gitignore
├── .gitmodules
├── CMakeLists.txt
├── LICENSE
├── Makefile
├── README.md
├── mayaConfigure.bat
├── modules
└── FindMaya.cmake
├── pythonConfigure.bat
├── src
├── lib
│ ├── combo.cpp
│ ├── combo.h
│ ├── enums.h
│ ├── floater.h
│ ├── progression.cpp
│ ├── progression.h
│ ├── shape.cpp
│ ├── shape.h
│ ├── shapeBase.h
│ ├── shapeController.cpp
│ ├── shapeController.h
│ ├── simplex.cpp
│ ├── simplex.h
│ ├── slider.cpp
│ ├── slider.h
│ ├── traversal.cpp
│ ├── traversal.h
│ ├── trispace.cpp
│ ├── trispace.h
│ ├── utils.cpp
│ └── utils.h
├── maya
│ ├── pluginMain.cpp
│ ├── simplex_mayaNode.cpp
│ └── simplex_mayaNode.h
├── python
│ └── simplex_python.cpp
└── xsi
│ ├── simplex_ice.cpp
│ └── simplex_ice.h
└── xsiConfigure.bat
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Release zipfile
6 | Simplex.zip
7 |
8 | # Build folders
9 | Maya20*/
10 | **/build/
11 | **/pybuild/
12 | **/mayabuild/
13 | **/mayabuild*/
14 | **/xsibuild/
15 | **/xsibuild*/
16 | **/output/
17 | **/output*/
18 | **/Useful/
19 |
20 | # VIM Swapfiles
21 | *.swp
22 |
23 | # Folder config file
24 | Desktop.ini
25 |
26 | # Recycle Bin used on file shares
27 | $RECYCLE.BIN/
28 |
29 | # Windows Installer files
30 | *.cab
31 | *.msi
32 | *.msm
33 | *.msp
34 |
35 | #python bytecode
36 | *.pyc
37 |
38 | # Windows shortcuts
39 | *.lnk
40 |
41 | # =========================
42 | # Operating System Files
43 | # =========================
44 |
45 | # OSX
46 | # =========================
47 |
48 | .DS_Store
49 | .AppleDouble
50 | .LSOverride
51 |
52 | # Thumbnails
53 | ._*
54 |
55 | # Files that might appear on external disk
56 | .Spotlight-V100
57 | .Trashes
58 |
59 | # Directories potentially created on remote AFP share
60 | .AppleDB
61 | .AppleDesktop
62 | Network Trash Folder
63 | Temporary Items
64 | .apdisk
65 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "include/eigen"]
2 | path = include/eigen
3 | url = https://github.com/eigenteam/eigen-git-mirror.git
4 | [submodule "include/rapidjson"]
5 | path = include/rapidjson
6 | url = https://github.com/Tencent/rapidjson.git
7 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.6)
2 |
3 | set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/modules)
4 | set(TARGET_DCC Maya CACHE STRING "Target Content Creation Package: Maya XSI Python")
5 |
6 | include_directories(src/lib include/rapidjson/include include/eigen)
7 |
8 | file(GLOB SOURCE_FILES
9 | "src/lib/*.h"
10 | "src/lib/*.cpp"
11 | )
12 |
13 | if (${TARGET_DCC} STREQUAL "Maya")
14 | project(simplex_maya)
15 | find_package(Maya REQUIRED)
16 | set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME})
17 | set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../output/${MAYA_VERSION})
18 |
19 | file(GLOB MAYA_FILES
20 | "src/maya/*.h"
21 | "src/maya/*.cpp"
22 | )
23 |
24 | include_directories(${MAYA_INCLUDE_DIR})
25 | link_directories(${MAYA_LIBRARY_DIR})
26 | add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${MAYA_FILES})
27 | target_link_libraries(${PROJECT_NAME} ${MAYA_LIBRARIES})
28 |
29 | MAYA_PLUGIN(${PROJECT_NAME})
30 | install(TARGETS ${PROJECT_NAME} DESTINATION blur/plug-ins)
31 | elseif(${TARGET_DCC} STREQUAL "XSI")
32 | project(simplex_ice)
33 | set(XSI_VERSION "2014 SP2" CACHE STRING "The XSI version")
34 |
35 | # XSI is dead, so not worth a cmake find
36 | # So, just set the data directly
37 | set(SI_HOME "C:/Program Files/Autodesk/Softimage ${XSI_VERSION}")
38 | set(XSISDK_ROOT ${SI_HOME}/XSISDK)
39 | set(XSI_LIB_DIR ${XSISDK_ROOT}/lib/nt-x86-64)
40 |
41 | set(XSI_INCLUDE_DIRS ${XSISDK_ROOT}/include)
42 | set(XSI_LIBRARIES
43 | "${XSI_LIB_DIR}/sicppsdk.lib"
44 | "${XSI_LIB_DIR}/sicoresdk.lib"
45 | )
46 |
47 | set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../output/XSI${XSI_VERSION})
48 | file(GLOB XSI_FILES
49 | "src/xsi/*.h"
50 | "src/xsi/*.cpp"
51 | )
52 | include_directories(${XSI_INCLUDE_DIRS})
53 | add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${XSI_FILES})
54 | target_link_libraries(${PROJECT_NAME} ${XSI_LIBRARIES})
55 | install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION plug-ins)
56 | elseif(${TARGET_DCC} STREQUAL "BlurPython")
57 | project(pysimplex)
58 |
59 | # Blergh, I can't do the normal find_package(PythonLibs REQUIRED)
60 | # we have to support 32 and 64 bit builds with strange paths
61 | # start annoying hard-coding
62 | set(PY_VERSION 27_64 CACHE STRING "The python version as part of the path")
63 | set(PY_PATH C:/Python${PY_VERSION})
64 | string(REPLACE "_" ";" _PY_VLIST ${PY_VERSION})
65 | list(GET _PY_VLIST 0 PY_SIMPLE_VERSION)
66 | set(PYTHON_INCLUDE_DIRS ${PY_PATH}/include)
67 | set(PYTHON_LIBRARIES ${PY_PATH}/libs/python${PY_SIMPLE_VERSION}.lib)
68 | # End annoying hard-coding
69 |
70 | set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../output/Python${PY_VERSION})
71 | file(GLOB PY_FILES
72 | "src/python/*.h"
73 | "src/python/*.cpp"
74 | )
75 | include_directories(${PYTHON_INCLUDE_DIRS})
76 | add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${PY_FILES})
77 | set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".pyd")
78 |
79 | if(WIN32)
80 | set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".pyd")
81 | else()
82 | set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
83 | set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".so")
84 | set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../output/python${PY_VERSION})
85 | endif()
86 |
87 | target_link_libraries(${PROJECT_NAME} ${PYTHON_LIBRARIES})
88 | message("Python Libraries: ${PYTHON_LIBRARIES}")
89 |
90 | install(TARGETS ${PROJECT_NAME}
91 | RUNTIME DESTINATION lib
92 | ARCHIVE DESTINATION lib
93 | )
94 | elseif(${TARGET_DCC} STREQUAL "Python")
95 | project(pysimplex)
96 | find_package(Python2 REQUIRED COMPONENTS Development)
97 |
98 | set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../output/Python${PY_VERSION})
99 | file(GLOB PY_FILES
100 | "src/python/*.h"
101 | "src/python/*.cpp"
102 | )
103 | include_directories(${Python2_INCLUDE_DIRS})
104 | add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${PY_FILES})
105 | if(WIN32)
106 | set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".pyd")
107 | else()
108 | set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
109 | set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".x86_64-linux-gnu.so")
110 | set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../output/python${PY_VERSION})
111 | endif()
112 |
113 | target_link_libraries(${PROJECT_NAME} ${Python2_LIBRARIES})
114 | message("Python Libraries: ${Python2_LIBRARIES}")
115 |
116 | install(TARGETS ${PROJECT_NAME}
117 | RUNTIME DESTINATION lib
118 | ARCHIVE DESTINATION lib
119 | )
120 |
121 | elseif(${TARGET_DCC} STREQUAL "Python3")
122 | project(pysimplex3)
123 | find_package(Python3 REQUIRED COMPONENTS Development)
124 |
125 | set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../output/Python${PY_VERSION})
126 | file(GLOB PY_FILES
127 | "src/python/*.h"
128 | "src/python/*.cpp"
129 | )
130 | include_directories(${Python3_INCLUDE_DIRS})
131 | add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${PY_FILES})
132 | if(WIN32)
133 | set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".pyd")
134 | else()
135 | set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
136 | set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".x86_64-linux-gnu.so")
137 | set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../output/python${PY_VERSION})
138 | endif()
139 |
140 | target_link_libraries(${PROJECT_NAME} ${Python3_LIBRARIES})
141 | message("Python Libraries: ${Python3_LIBRARIES}")
142 |
143 | install(TARGETS ${PROJECT_NAME}
144 | RUNTIME DESTINATION lib
145 | ARCHIVE DESTINATION lib
146 | )
147 |
148 | elseif(${TARGET_DCC} STREQUAL "Test")
149 | project(pysimplex)
150 | file(GLOB TEST_FILES
151 | "src/test/*.h"
152 | "src/test/*.cpp"
153 | )
154 | add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${TEST_FILES})
155 | else()
156 | message(FATAL_ERROR "Improper DCC Specified. Must be either Maya or XSI")
157 | endif()
158 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: \
2 | help \
3 | generate_maya \
4 | generate_python \
5 | generate_xsi \
6 | build_maya \
7 | build_python \
8 | build_xsi \
9 | install_maya \
10 | install_python \
11 | install_xsi \
12 | clean \
13 |
14 |
15 | CMAKE = cmake
16 |
17 | MAYA_VERSION = 2019
18 | MAYA_BUILD_DIR = mayabuild
19 |
20 | PYTHON_VERSION = 2.7
21 | PYTHON_BUILD_DIR = pybuild
22 |
23 | XSI_VERSION = 2015
24 | XSI_BUILD_DIR = xsibuild
25 |
26 | #-----------------------------------------------------------------------------#
27 | # cmake generate targets
28 | #-----------------------------------------------------------------------------#
29 |
30 | generate_maya::
31 | rm -rf $(MAYA_BUILD_DIR)
32 | mkdir -p $(MAYA_BUILD_DIR)
33 | $(CMAKE) -DMAYA_VERSION=$(MAYA_VERSION) -B$(MAYA_BUILD_DIR)
34 |
35 | generate_python::
36 | rm -rf $(PYTHON_BUILD_DIR)
37 | mkdir -p $(PYTHON_BUILD_DIR)
38 | $(CMAKE) -DPY_VERSION=$(PYTHON_VERSION) -DTARGET_DCC=Python -B$(PYTHON_BUILD_DIR)
39 |
40 | generate_xsi::
41 | rm -rf $(XSI_BUILD_DIR)
42 | mkdir -p $(XSI_BUILD_DIR)
43 | $(CMAKE) -DXSI_VERSION=$(XSI_VERSION) -DTARGET_DCC=XSI -B$(XSI_BUILD_DIR)
44 |
45 | #-----------------------------------------------------------------------------#
46 | # cmake build targets
47 | #-----------------------------------------------------------------------------#
48 |
49 | build_maya::
50 | cmake --build $(MAYA_BUILD_DIR) --config Release
51 |
52 | build_python::
53 | cmake --build $(PYTHON_BUILD_DIR) --config Release
54 |
55 | build_xsi::
56 | cmake --build $(XSI_BUILD_DIR) --config Release
57 |
58 | #-----------------------------------------------------------------------------#
59 | # cmake build targets
60 | #-----------------------------------------------------------------------------#
61 |
62 | install_maya::
63 | cmake --install $(MAYA_BUILD_DIR) --config Release
64 |
65 | install_python::
66 | cmake --install $(PYTHON_BUILD_DIR) --config Release
67 |
68 | install_xsi::
69 | cmake --install $(XSI_BUILD_DIR) --config Release
70 |
71 |
72 | clean::
73 | rm -rf $(MAYA_BUILD_DIR)
74 | rm -rf $(PYTHON_BUILD_DIR)
75 | rm -rf $(XSI_BUILD_DIR)
76 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Development for this repo has moved
2 |
3 | Development repositories for the c++ and python parts of Simplex have been combined, so this repository will no longer recieve updates. The main Simplex repo, however, is still under active use.
4 |
5 | https://github.com/blurstudio/Simplex
6 |
7 |
--------------------------------------------------------------------------------
/mayaConfigure.bat:
--------------------------------------------------------------------------------
1 | setlocal
2 |
3 | SET MAYA_VERSION=2022
4 | SET BUILD=mayabuild_%MAYA_VERSION%
5 | SET COMPILER=Visual Studio 15 2017 Win64
6 |
7 | SET PFX=%~dp0
8 | cd %PFX%
9 | rmdir %BUILD% /s /q
10 | mkdir %BUILD%
11 | cd %BUILD%
12 |
13 | cmake ^
14 | -DMAYA_VERSION=%MAYA_VERSION% ^
15 | -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ^
16 | -G "%COMPILER%" ..\
17 |
18 | cmake --build . --config Release --target INSTALL
19 |
20 | pause
21 |
--------------------------------------------------------------------------------
/modules/FindMaya.cmake:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 | #
3 | # Copyright (c) 2015 Chad Vernon
4 | #
5 | # Permission is hereby granted, free of charge, to any person obtaining a copy
6 | # of this software and associated documentation files (the "Software"), to deal
7 | # in the Software without restriction, including without limitation the rights
8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | # copies of the Software, and to permit persons to whom the Software is
10 | # furnished to do so, subject to the following conditions:
11 | #
12 | # The above copyright notice and this permission notice shall be included in all
13 | # copies or substantial portions of the Software.
14 | #
15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | # SOFTWARE.
22 |
23 | # - Maya finder module
24 | #
25 | # Variables that will be defined:
26 | # MAYA_FOUND Defined if a Maya installation has been detected
27 | # MAYA_EXECUTABLE Path to Maya's executable
28 | # MAYA__FOUND Defined if has been found
29 | # MAYA__LIBRARY Path to library
30 | # MAYA_INCLUDE_DIR Path to the devkit's include directories
31 | # MAYA_LIBRARIES All the Maya libraries
32 | #
33 |
34 | # Set a default Maya version if not specified
35 | if(NOT DEFINED MAYA_VERSION)
36 | set(MAYA_VERSION 2016 CACHE STRING "Maya version")
37 | endif()
38 |
39 | # OS Specific environment setup
40 | set(MAYA_COMPILE_DEFINITIONS "REQUIRE_IOSTREAM;_BOOL")
41 | set(MAYA_INSTALL_BASE_SUFFIX "")
42 | set(MAYA_INC_SUFFIX "include")
43 | set(MAYA_LIB_SUFFIX "lib")
44 | set(MAYA_BIN_SUFFIX "bin")
45 | set(MAYA_TARGET_TYPE LIBRARY)
46 | if(WIN32)
47 | # Windows
48 | set(MAYA_INSTALL_BASE_DEFAULT "C:/Program Files/Autodesk")
49 | set(MAYA_COMPILE_DEFINITIONS "${MAYA_COMPILE_DEFINITIONS};NT_PLUGIN")
50 | set(OPENMAYA OpenMaya.lib)
51 | set(MAYA_PLUGIN_EXTENSION ".mll")
52 | set(MAYA_TARGET_TYPE RUNTIME)
53 | elseif(APPLE)
54 | # Apple
55 | set(MAYA_INSTALL_BASE_DEFAULT /Applications/Autodesk)
56 | set(MAYA_INC_SUFFIX "devkit/include")
57 | set(MAYA_LIB_SUFFIX "Maya.app/Contents/MacOS")
58 | set(MAYA_BIN_SUFFIX "Maya.app/Contents/bin/")
59 | set(MAYA_COMPILE_DEFINITIONS "${MAYA_COMPILE_DEFINITIONS};OSMac_")
60 | set(OPENMAYA libOpenMaya.dylib)
61 | set(MAYA_PLUGIN_EXTENSION ".bundle")
62 | else()
63 | # Linux
64 | set(MAYA_COMPILE_DEFINITIONS "${MAYA_COMPILE_DEFINITIONS};LINUX")
65 | set(MAYA_INSTALL_BASE_DEFAULT /usr/autodesk)
66 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
67 | if(MAYA_VERSION LESS 2016)
68 | SET(MAYA_INSTALL_BASE_SUFFIX -x64)
69 | endif()
70 | set(OPENMAYA libOpenMaya.so)
71 | set(MAYA_PLUGIN_EXTENSION ".so")
72 | endif()
73 |
74 | set(MAYA_INSTALL_BASE_PATH ${MAYA_INSTALL_BASE_DEFAULT} CACHE STRING
75 | "Root path containing your maya installations, e.g. /usr/autodesk or /Applications/Autodesk/")
76 |
77 | if(NOT DEFINED MAYA_LOCATION)
78 | if(WIN32)
79 | set(MAYA_LOCATION ${MAYA_INSTALL_BASE_PATH}/Maya${MAYA_VERSION}${MAYA_INSTALL_BASE_SUFFIX})
80 | else()
81 | set(MAYA_LOCATION ${MAYA_INSTALL_BASE_PATH}/maya)
82 | endif()
83 | endif()
84 |
85 | # Maya library directory
86 | find_path(MAYA_LIBRARY_DIR ${OPENMAYA}
87 | PATHS
88 | ${MAYA_LOCATION}
89 | $ENV{MAYA_LOCATION}
90 | PATH_SUFFIXES
91 | "${MAYA_LIB_SUFFIX}/"
92 | DOC "Maya library path"
93 | )
94 |
95 | # Maya include directory
96 | find_path(MAYA_INCLUDE_DIR maya/MFn.h
97 | PATHS
98 | ${MAYA_LOCATION}
99 | $ENV{MAYA_LOCATION}
100 | PATH_SUFFIXES
101 | "${MAYA_INC_SUFFIX}/"
102 | DOC "Maya include path"
103 | )
104 |
105 | # Maya libraries
106 | set(_MAYA_LIBRARIES OpenMaya OpenMayaAnim OpenMayaFX OpenMayaRender OpenMayaUI Foundation clew)
107 | foreach(MAYA_LIB ${_MAYA_LIBRARIES})
108 | find_library(MAYA_${MAYA_LIB}_LIBRARY NAMES ${MAYA_LIB} PATHS ${MAYA_LIBRARY_DIR}
109 | NO_DEFAULT_PATH)
110 | if (MAYA_${MAYA_LIB}_LIBRARY)
111 | set(MAYA_LIBRARIES ${MAYA_LIBRARIES} ${MAYA_${MAYA_LIB}_LIBRARY})
112 | endif()
113 | endforeach()
114 |
115 | if (APPLE AND ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
116 | # Clang and Maya needs to use libstdc++
117 | set(MAYA_CXX_FLAGS "-std=c++0x -stdlib=libstdc++")
118 | endif()
119 |
120 | include(FindPackageHandleStandardArgs)
121 | find_package_handle_standard_args(Maya DEFAULT_MSG MAYA_INCLUDE_DIR MAYA_LIBRARIES)
122 |
123 | function(MAYA_PLUGIN _target)
124 | if (WIN32)
125 | set_target_properties(${_target} PROPERTIES
126 | LINK_FLAGS "/export:initializePlugin /export:uninitializePlugin"
127 | )
128 | endif()
129 | set_target_properties(${_target} PROPERTIES
130 | COMPILE_DEFINITIONS "${MAYA_COMPILE_DEFINITIONS}"
131 | PREFIX ""
132 | SUFFIX ${MAYA_PLUGIN_EXTENSION})
133 | endfunction()
134 |
--------------------------------------------------------------------------------
/pythonConfigure.bat:
--------------------------------------------------------------------------------
1 | setlocal
2 |
3 | SET BUILD=pybuild
4 | SET PY_VERSION=37
5 | SET ARCH=64
6 | SET COMPILER=Visual Studio 16 2019
7 |
8 | SET PFX=%~dp0
9 | cd %PFX%
10 | rmdir %BUILD% /s /q
11 | mkdir %BUILD%
12 | cd %BUILD%
13 |
14 |
15 | if "%ARCH%" == "64" (
16 | set PY_VERSION=%PY_VERSION%_64
17 | if "%COMPILER%" NEQ "Visual Studio 16 2019" (
18 | SET COMPILER=%COMPILER% Win64
19 | )
20 | )
21 |
22 | cmake ^
23 | -DTARGET_DCC=Python3 ^
24 | -DPY_VERSION=%PY_VERSION% ^
25 | -G "%COMPILER%" ..\
26 |
27 | cmake --build . --config Release --target INSTALL
28 |
29 | pause
30 |
31 |
--------------------------------------------------------------------------------
/src/lib/combo.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #include "enums.h"
21 | #include "utils.h"
22 | #include "shapeController.h"
23 | #include "slider.h"
24 | #include "combo.h"
25 | #include "floater.h"
26 | #include "simplex.h"
27 |
28 | #include "rapidjson/rapidjson.h"
29 | #include "math.h"
30 |
31 | #include // for sort
32 | #include // for numeric_limits
33 |
34 | using namespace simplex;
35 | class simplex::Progression;
36 |
37 |
38 | bool simplex::solveState(const std::vector &vals, const std::vector &tars, ComboSolve solveType, bool exact, double &value) {
39 | double mn, mx, allMul = 1.0, allSum = 0.0;
40 | mn = std::numeric_limits::infinity();
41 | mx = -mn;
42 |
43 | for (size_t i = 0; i < vals.size(); ++i){
44 | double val = vals[i];
45 | double tar = tars[i];
46 |
47 | // Specifically this instead of isNegative()
48 | // because isNegative returns true for 0.0
49 | bool valNeg = !isPositive(val);
50 | bool tarNeg = !isPositive(tar);
51 |
52 | if (valNeg != tarNeg) return false;
53 | if (valNeg) val = -val;
54 |
55 | val = (val > MAXVAL) ? MAXVAL : val;
56 | allMul *= val;
57 | allSum += val;
58 | if (val < mn) mn = val;
59 | if (val > mx) mx = val;
60 | }
61 |
62 | switch (solveType) {
63 | case ComboSolve::min:
64 | value = (exact) ? mn : doSoftMin(mx, mn);
65 | break;
66 | case ComboSolve::allMul:
67 | value = allMul;
68 | break;
69 | case ComboSolve::extMul:
70 | value = mx * mn;
71 | break;
72 | case ComboSolve::mulAvgExt:
73 | if (isZero(mx + mn))
74 | value = 0.0;
75 | else
76 | value = 2 * (mx * mn) / (mx + mn);
77 | break;
78 | case ComboSolve::mulAvgAll:
79 | if (isZero(allSum))
80 | value = 0.0;
81 | else
82 | value = vals.size() * allMul / allSum;
83 | break;
84 | case ComboSolve::None:
85 | value = (exact) ? mn : doSoftMin(mx, mn);
86 | break;
87 | default:
88 | value = (exact) ? mn : doSoftMin(mx, mn);
89 | }
90 | return true;
91 | }
92 |
93 | bool simplex::solveState(const ComboPairs &stateList, ComboSolve solveType, bool exact, double &value) {
94 | std::vector vals, tars;
95 | for (auto sit = stateList.begin(); sit != stateList.end(); ++sit) {
96 | //for (const auto &state: stateList){
97 | const auto &state = *sit;
98 | vals.push_back(state.first->getValue());
99 | tars.push_back(state.second);
100 | }
101 | return simplex::solveState(vals, tars, solveType, exact, value);
102 | }
103 |
104 | ComboSolve simplex::getSolveType(const rapidjson::Value &val) {
105 | ComboSolve solveType = ComboSolve::None;
106 | auto solveIt = val.FindMember("solveType");
107 | if (solveIt != val.MemberEnd()) {
108 | if (!solveIt->value.IsString()) {
109 | solveType = ComboSolve::None;
110 | }
111 | else {
112 | std::string solve(solveIt->value.GetString());
113 | if (solve == "min")
114 | solveType = ComboSolve::min;
115 | else if (solve == "allMul")
116 | solveType = ComboSolve::allMul;
117 | else if (solve == "extMul")
118 | solveType = ComboSolve::extMul;
119 | else if (solve == "mulAvgExt")
120 | solveType = ComboSolve::mulAvgExt;
121 | else if (solve == "mulAvgAll")
122 | solveType = ComboSolve::mulAvgAll;
123 | else if (solve == "None")
124 | solveType = ComboSolve::None;
125 | else
126 | solveType = ComboSolve::None;
127 | }
128 | }
129 | return solveType;
130 | }
131 |
132 | bool simplex::getSolvePairs(const rapidjson::Value &val, Simplex *simp, ComboPairs &state, bool &isFloater) {
133 | for (auto it = val.Begin(); it != val.End(); ++it) {
134 | auto &ival = *it;
135 | if (!ival.IsArray()) return false;
136 | if (!ival[0].IsInt()) return false;
137 | if (!ival[1].IsDouble()) return false;
138 |
139 | size_t slidx = (size_t)ival[0].GetInt();
140 | double slval = (double)ival[1].GetDouble();
141 | if (!floatEQ(fabs(slval), 1.0, EPS) && !isZero(slval))
142 | isFloater = true;
143 | if (slidx >= simp->sliders.size()) return false;
144 | state.push_back(std::make_pair(&simp->sliders[slidx], slval));
145 | }
146 | return true;
147 | }
148 |
149 | Combo::Combo(const std::string &name, Progression* prog, size_t index,
150 | const ComboPairs &stateList, bool isFloater, ComboSolve solveType) :
151 | ShapeController(name, prog, index), stateList(stateList), isFloater(isFloater), solveType(solveType), exact(true) {
152 | std::sort(this->stateList.begin(), this->stateList.end(),
153 | [](const ComboPair &lhs, const ComboPair &rhs) {
154 | return lhs.first->getIndex() < rhs.first->getIndex();
155 | }
156 | );
157 | std::vector rawVec;
158 | for (auto pit = this->stateList.begin(); pit != this->stateList.end(); ++pit) {
159 | //for (auto &p : this->stateList) {
160 | auto &p = *pit;
161 | rawVec.push_back(p.second);
162 | }
163 | rectify(rawVec, rectified, clamped, inverted);
164 | }
165 |
166 | void Combo::storeValue(
167 | const std::vector &values,
168 | const std::vector &posValues,
169 | const std::vector &clamped,
170 | const std::vector &inverses) {
171 |
172 | if (!enabled) return;
173 | if (isFloater) return;
174 | solveState(stateList, solveType, exact, value);
175 | }
176 |
177 | bool Combo::parseJSONv1(const rapidjson::Value &val, size_t index, Simplex *simp) {
178 | if (!val[0u].IsString()) return false;
179 | if (!val[1].IsInt()) return false;
180 | const rapidjson::Value &jcstate = val[2];
181 | ComboPairs state;
182 |
183 | bool isFloater = false;
184 | rapidjson::SizeType j;
185 | for (j = 0; j < jcstate.Size(); ++j) {
186 | if (!jcstate[j][0u].IsInt()) return false;
187 | if (!jcstate[j][1].IsNumber()) return false;
188 | size_t slidx = (size_t)jcstate[j][0u].GetInt();
189 | double slval = jcstate[j][1].GetDouble();
190 |
191 | if (!floatEQ(fabs(slval), 1.0, EPS) && !isZero(slval))
192 | isFloater = true;
193 |
194 | if (slidx >= simp->sliders.size()) return false;
195 | state.push_back(std::make_pair(&simp->sliders[slidx], slval));
196 | }
197 |
198 | std::string name(val[0u].GetString());
199 | size_t pidx = (size_t)val[1].GetInt();
200 | if (pidx >= simp->progs.size()) return false;
201 | if (isFloater)
202 | simp->floaters.push_back(Floater(name, &simp->progs[pidx], index, state, isFloater));
203 | simp->combos.push_back(Combo(name, &simp->progs[pidx], index, state, isFloater, ComboSolve::None));
204 | return true;
205 | }
206 |
207 | bool Combo::parseJSONv2(const rapidjson::Value &val, size_t index, Simplex *simp) {
208 | if (!val.IsObject()) return false;
209 | CHECK_JSON_STRING(nameIt, "name", val);
210 | CHECK_JSON_INT(progIt, "prog", val);
211 | CHECK_JSON_ARRAY(pairsIt, "pairs", val);
212 |
213 | std::string name(nameIt->value.GetString());
214 |
215 | ComboSolve solveType = getSolveType(val);
216 | ComboPairs state;
217 | bool isFloater = false;
218 | auto &pairsVal = pairsIt->value;
219 | if (!getSolvePairs(pairsVal, simp, state, isFloater)) return false;
220 |
221 | size_t pidx = (size_t)progIt->value.GetInt();
222 | if (pidx >= simp->progs.size()) return false;
223 |
224 | bool enabled = getEnabled(val);
225 |
226 | if (isFloater) {
227 | simp->floaters.push_back(Floater(name, &simp->progs[pidx], index, state, isFloater));
228 | simp->floaters.back().setEnabled(enabled);
229 | }
230 | // because a floater is still considered a combo
231 | // I need to add it to the list for indexing purposes
232 |
233 | simp->combos.push_back(Combo(name, &simp->progs[pidx], index, state, isFloater, solveType));
234 | simp->combos.back().setEnabled(enabled);
235 | return true;
236 | }
237 |
238 | bool Combo::parseJSONv3(const rapidjson::Value &val, size_t index, Simplex *simp) {
239 | return parseJSONv2(val, index, simp);
240 | }
241 |
242 |
--------------------------------------------------------------------------------
/src/lib/combo.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include "enums.h"
23 | #include "shapeController.h"
24 | #include "rapidjson/document.h"
25 |
26 | #include
27 | #include
28 | #include
29 |
30 | namespace simplex {
31 |
32 | class Progression;
33 | class Slider;
34 | class Simplex;
35 |
36 | typedef std::pair ComboPair;
37 | typedef std::vector ComboPairs;
38 |
39 | ComboSolve getSolveType(const rapidjson::Value &val);
40 | bool getSolvePairs(const rapidjson::Value &val, Simplex *simp, ComboPairs &state, bool &isFloater);
41 |
42 | bool solveState(const std::vector &vals, const std::vector &tars, ComboSolve solveType, bool exact, double &value);
43 | bool solveState(const ComboPairs &stateList, ComboSolve solveType, bool exact, double &value);
44 |
45 | class Combo : public ShapeController {
46 | private:
47 | bool isFloater;
48 | bool exact;
49 | ComboSolve solveType;
50 | protected:
51 | std::vector inverted;
52 | std::vector rectified;
53 | std::vector clamped;
54 | public:
55 | ComboPairs stateList;
56 | bool sliderType() const override { return false; }
57 | void setExact(bool e){exact = e;}
58 | Combo(const std::string &name, Progression* prog, size_t index,
59 | const ComboPairs &stateList, bool isFloater, ComboSolve solveType);
60 | void storeValue(
61 | const std::vector &values,
62 | const std::vector &posValues,
63 | const std::vector &clamped,
64 | const std::vector &inverses);
65 | static bool parseJSONv1(const rapidjson::Value &val, size_t index, Simplex *simp);
66 | static bool parseJSONv2(const rapidjson::Value &val, size_t index, Simplex *simp);
67 | static bool parseJSONv3(const rapidjson::Value &val, size_t index, Simplex *simp);
68 | };
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/src/lib/enums.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 | #pragma once
20 |
21 | namespace simplex {
22 |
23 | enum ProgType {linear, spline, splitSpline};
24 | enum ComboSolve {min, allMul, extMul, mulAvgAll, mulAvgExt, None};
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/lib/floater.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include "enums.h"
23 | #include "combo.h"
24 |
25 | #include
26 | #include
27 | #include
28 |
29 | namespace simplex {
30 |
31 | class Slider;
32 | class Floater : public Combo {
33 | public:
34 | friend class TriSpace; // lets the trispace set the value for this guy
35 | Floater(const std::string &name, Progression* prog, size_t index,
36 | const std::vector> &stateList, bool isFloater) :
37 | Combo(name, prog, index, stateList, isFloater, ComboSolve::None) {
38 | }
39 | };
40 |
41 |
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/src/lib/progression.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #include "shapeBase.h"
21 | #include "progression.h"
22 | #include "simplex.h"
23 | #include "enums.h"
24 |
25 | #include "rapidjson/document.h"
26 | #include "rapidjson/rapidjson.h"
27 |
28 | #include // for sort
29 | #include
30 | #include
31 | #include
32 |
33 | using namespace simplex;
34 | class simplex::Shape;
35 |
36 | Progression::Progression(const std::string &name, const ProgPairs &pairs, ProgType interp):
37 | ShapeBase(name), pairs(pairs), interp(interp) {
38 | std::sort(this->pairs.begin(), this->pairs.end(),
39 | [](const ProgPair &a, const ProgPair &b) {
40 | return a.second < b.second;
41 | }
42 | );
43 | }
44 |
45 | size_t Progression::getInterval(double tVal, const std::vector ×, bool &outside){
46 | if (times.size() <= 1){
47 | outside = true;
48 | return 0;
49 | }
50 | outside = tVal < times[0] || tVal > times[times.size() - 1];
51 | if (tVal >= times[times.size() - 2]){
52 | return times.size() - 2;
53 | }
54 | else if (tVal < times[0]){
55 | return 0;
56 | }
57 | else{
58 | // the percent for the current segment of tVal
59 | // and the corresponding basis values
60 | for (size_t i=0; i sided;
71 | for (size_t i = 0; i < pairs.size(); ++i) {
72 | sided.push_back(&(pairs[i]));
73 | }
74 | return getRawSplineOutput(sided, tVal, mul);
75 | }
76 |
77 | ProgPairs Progression::getSplitSplineOutput(double tVal, double mul) const{
78 | std::vector sided;
79 | bool gt = tVal >= 0.0;
80 | for (size_t i = 0; i < pairs.size(); ++i) {
81 | if (gt && pairs[i].second >= 0)
82 | sided.push_back(&(pairs[i]));
83 | else if (!gt && pairs[i].second <= 0)
84 | sided.push_back(&(pairs[i]));
85 | }
86 | return getRawSplineOutput(sided, tVal, mul);
87 | }
88 |
89 | ProgPairs Progression::getLinearOutput(double tVal, double mul) const{
90 | std::vector sided;
91 | for (size_t i = 0; i < pairs.size(); ++i) {
92 | sided.push_back(&(pairs[i]));
93 | }
94 | return getRawLinearOutput(sided, tVal, mul);
95 | }
96 |
97 | ProgPairs Progression::getRawSplineOutput(const std::vector* > pairs, double tVal, double mul){
98 | if (
99 | (pairs.size() <= 2) ||
100 | (tVal < pairs[0]->second) && (tVal > pairs[pairs.size()-1]->second)
101 | ){
102 | return getRawLinearOutput(pairs, tVal, mul);
103 | }
104 |
105 | std::vector shapes;
106 | std::vector st;
107 | for (auto it = pairs.begin(); it != pairs.end(); ++it){
108 | shapes.push_back((*it)->first);
109 | st.push_back((*it)->second);
110 | }
111 | bool outside = false;
112 | size_t interval = getInterval(tVal, st, outside);
113 | ProgPairs out;
114 |
115 | double start = st[interval];
116 | double end = st[interval + 1];
117 |
118 | //# compute the catmull-rom basis multipliers
119 | double x = (tVal - start) / (end - start);
120 | if (outside) {
121 | // If I'm outside the range of the spline, then I linear interpolate along the implicit tangent
122 | if (interval == 0) {
123 | out.push_back(std::make_pair(shapes[0], mul * (1.0 - x)));
124 | out.push_back(std::make_pair(shapes[1], mul * x));
125 | }
126 | else {
127 | out.push_back(std::make_pair(shapes[shapes.size() - 1], mul * x));
128 | out.push_back(std::make_pair(shapes[shapes.size() - 2], mul * (1.0 - x)));
129 | }
130 | }
131 | else{
132 | double x2 = x*x;
133 | double x3 = x2*x;
134 | double v0 = (-0.5*x3 + 1.0*x2 - 0.5*x);
135 | double v1 = (1.5*x3 - 2.5*x2 + 1.0);
136 | double v2 = (-1.5*x3 + 2.0*x2 + 0.5*x);
137 | double v3 = (0.5*x3 - 0.5*x2);
138 | if (interval == 0) { // deal with input tangent
139 | out.push_back(std::make_pair(shapes[0], mul * (v1 + v0 + v0)));
140 | out.push_back(std::make_pair(shapes[1], mul * (v2 - v0)));
141 | out.push_back(std::make_pair(shapes[2], mul * (v3)));
142 | }
143 | else if (interval == st.size() - 2) { // deal with output tangent
144 | out.push_back(std::make_pair(shapes[shapes.size() - 3], mul * (v0)));
145 | out.push_back(std::make_pair(shapes[shapes.size() - 2], mul * (v1 - v3)));
146 | out.push_back(std::make_pair(shapes[shapes.size() - 1], mul * (v2 + v3 + v3)));
147 | }
148 | else {
149 | out.push_back(std::make_pair(shapes[interval - 1], mul * v0));
150 | out.push_back(std::make_pair(shapes[interval + 0], mul * v1));
151 | out.push_back(std::make_pair(shapes[interval + 1], mul * v2));
152 | out.push_back(std::make_pair(shapes[interval + 2], mul * v3));
153 | }
154 | }
155 | return out;
156 | }
157 |
158 | ProgPairs Progression::getRawLinearOutput(const std::vector* > pairs, double tVal, double mul){
159 | ProgPairs out;
160 | std::vector times;
161 | if (pairs.size() < 2) return out;
162 |
163 | for (auto it=pairs.begin(); it!=pairs.end(); ++it){
164 | times.push_back((*it)->second);
165 | }
166 | bool outside;
167 | size_t idx = getInterval(tVal, times, outside);
168 | double u = (tVal - times[idx]) / (times[idx+1] - times[idx]);
169 | out.push_back(std::make_pair(pairs[idx]->first, mul * (1.0-u)));
170 | out.push_back(std::make_pair(pairs[idx+1]->first, mul * u));
171 | return out;
172 | }
173 |
174 | ProgPairs Progression::getOutput(double tVal, double mul) const{
175 | if (interp == ProgType::spline)
176 | return getSplineOutput(tVal, mul);
177 | else if (interp == ProgType::splitSpline)
178 | return getSplitSplineOutput(tVal, mul);
179 | else // if (interp == ProgType::linear)
180 | return getLinearOutput(tVal, mul);
181 | }
182 |
183 | bool Progression::parseJSONv1(const rapidjson::Value &val, size_t index, Simplex *simp){
184 | if (!val.IsArray()) return false;
185 |
186 | ProgPairs pairs;
187 | const rapidjson::Value &jindices = val[1];
188 | const rapidjson::Value &jweights = val[2];
189 | if (!jweights.IsArray() || !jindices.IsArray()) return false;
190 |
191 | rapidjson::SizeType j;
192 | for (j = 0; j= simp->shapes.size()) return false;
198 | pairs.push_back(std::make_pair(&simp->shapes[x], y));
199 | }
200 |
201 | if (!val[0u].IsString()) return false;
202 | std::string name(val[0u].GetString());
203 |
204 | ProgType interp = ProgType::spline;
205 |
206 | if (val.Size() > 3){
207 | if (!val[3].IsString()) return false;
208 | std::string interpStr = val[3].GetString();
209 | if (interpStr == "linear") {
210 | interp = ProgType::linear;
211 | }
212 | }
213 | simp->progs.push_back(Progression(name, pairs, interp));
214 | return true;
215 | }
216 |
217 | bool Progression::parseJSONv2(const rapidjson::Value &val, size_t index, Simplex *simp){
218 | if (!val.IsObject()) return false;
219 |
220 | CHECK_JSON_STRING(nameIt, "name", val);
221 | CHECK_JSON_ARRAY(pairsIt, "pairs", val);
222 | CHECK_JSON_STRING(interpIt, "interp", val);
223 |
224 | std::string name(nameIt->value.GetString());
225 |
226 | std::string interpStr(interpIt->value.GetString());
227 | ProgType interp = ProgType::spline;
228 | if (interpStr == "linear")
229 | interp = ProgType::linear;
230 | else if (interpStr == "splitspline")
231 | interp = ProgType::splitSpline;
232 |
233 | ProgPairs pairs;
234 |
235 | auto &pairsVal = pairsIt->value;
236 | for (auto it = pairsVal.Begin(); it != pairsVal.End(); ++it){
237 | auto &ival = *it;
238 | if (!ival.IsArray()) return false;
239 | if (!ival[0].IsInt()) return false;
240 | if (!ival[1].IsDouble()) return false;
241 |
242 | size_t x = (size_t)ival[0].GetInt();
243 | double y = (double)ival[1].GetDouble();
244 |
245 | if (x >= simp->shapes.size()) return false;
246 | pairs.push_back(std::make_pair(&simp->shapes[x], y));
247 | }
248 | simp->progs.push_back(Progression(name, pairs, interp));
249 | return true;
250 | }
251 |
252 | bool Progression::parseJSONv3(const rapidjson::Value &val, size_t index, Simplex *simp){
253 | return parseJSONv2(val, index, simp);
254 | }
255 |
256 |
257 |
--------------------------------------------------------------------------------
/src/lib/progression.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include "enums.h"
23 | #include "shapeBase.h"
24 | #include "rapidjson/document.h"
25 |
26 | #include
27 | #include
28 | #include
29 |
30 |
31 | namespace simplex {
32 |
33 | class Simplex;
34 | class Shape;
35 |
36 | typedef std::pair ProgPair;
37 | typedef std::vector ProgPairs;
38 |
39 | class Progression : public ShapeBase {
40 | private:
41 | ProgPairs pairs;
42 | ProgType interp;
43 | static size_t getInterval(double tVal, const std::vector ×, bool &outside);
44 | ProgPairs getSplineOutput(double tVal, double mul=1.0) const;
45 | ProgPairs getSplitSplineOutput(double tVal, double mul=1.0) const;
46 | ProgPairs getLinearOutput(double tVal, double mul=1.0) const;
47 |
48 | static ProgPairs getRawSplineOutput(const std::vector* > pairs, double tVal, double mul=1.0);
49 | static ProgPairs getRawLinearOutput(const std::vector* > pairs, double tVal, double mul=1.0);
50 |
51 | public:
52 | ProgPairs getOutput(double tVal, double mul=1.0) const;
53 |
54 | Progression(const std::string &name, const ProgPairs &pairs, ProgType interp);
55 | static bool parseJSONv1(const rapidjson::Value &val, size_t index, Simplex *simp);
56 | static bool parseJSONv2(const rapidjson::Value &val, size_t index, Simplex *simp);
57 | static bool parseJSONv3(const rapidjson::Value &val, size_t index, Simplex *simp);
58 | };
59 |
60 |
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/src/lib/shape.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 | #include "simplex.h"
20 | #include "shape.h"
21 |
22 | #include "rapidjson/document.h"
23 |
24 | #include
25 | #include
26 |
27 | using namespace simplex;
28 |
29 | bool Shape::parseJSONv1(const rapidjson::Value &val, size_t index, Simplex *simp){
30 | if(!val.IsString()) return false;
31 | std::string name(val.GetString());
32 | simp->shapes.push_back(Shape(name, index));
33 | return true;
34 | }
35 |
36 | bool Shape::parseJSONv2(const rapidjson::Value &val, size_t index, Simplex *simp){
37 | if (!val.IsObject()) return false;
38 |
39 | CHECK_JSON_STRING(nameIt, "name", val);
40 |
41 | std::string name(nameIt->value.GetString());
42 | simp->shapes.push_back(Shape(name, index));
43 | return true;
44 | }
45 |
46 | bool Shape::parseJSONv3(const rapidjson::Value &val, size_t index, Simplex *simp){
47 | return parseJSONv2(val, index, simp);
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/src/lib/shape.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include "shapeBase.h"
23 | #include "rapidjson/document.h"
24 | #include
25 |
26 | namespace simplex {
27 |
28 | class Simplex;
29 |
30 | class Shape : public ShapeBase {
31 | public:
32 | Shape(const std::string &name, size_t index): ShapeBase(name, index){}
33 | static bool parseJSONv1(const rapidjson::Value &val, size_t index, Simplex *simp);
34 | static bool parseJSONv2(const rapidjson::Value &val, size_t index, Simplex *simp);
35 | static bool parseJSONv3(const rapidjson::Value &val, size_t index, Simplex *simp);
36 | };
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/lib/shapeBase.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include "enums.h"
23 | #include
24 |
25 | namespace simplex {
26 |
27 | class ShapeBase {
28 | protected:
29 | void *shapeRef; // pointer to whatever the user wants
30 | std::string name;
31 | size_t index;
32 | public:
33 | explicit ShapeBase(const std::string &name, size_t index): name(name), index(index), shapeRef(nullptr) {}
34 | explicit ShapeBase(const std::string &name): name(name), index(0u), shapeRef(nullptr) {}
35 | const std::string* getName() const {return &name;}
36 | const size_t getIndex() const { return index; }
37 | void setUserData(void *data) {shapeRef = data;}
38 | void* getUserData(){return shapeRef;}
39 | };
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/lib/shapeController.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 | #include "simplex.h"
20 | #include "shapeController.h"
21 | #include "progression.h"
22 | #include "shape.h"
23 |
24 | #include
25 | #include
26 | #include "math.h"
27 |
28 | using namespace simplex;
29 |
30 | void ShapeController::solve(std::vector &accumulator, double &maxAct) const {
31 | double vm = fabs(value * multiplier);
32 | if (vm > maxAct) maxAct = vm;
33 |
34 | ProgPairs shapeVals = prog->getOutput(value, multiplier);
35 | for (auto sit=shapeVals.begin(); sit!=shapeVals.end(); ++sit){
36 | //for (const auto &svp: shapeVals){
37 | const auto &svp = *sit;
38 | accumulator[svp.first->getIndex()] += svp.second;
39 | }
40 | }
41 |
42 | bool ShapeController::getEnabled(const rapidjson::Value &val) {
43 | auto enIt = val.FindMember("enabled");
44 | if (enIt != val.MemberEnd()) {
45 | if (enIt->value.IsBool()) {
46 | return enIt->value.GetBool();
47 | }
48 | }
49 | return true;
50 | }
51 |
--------------------------------------------------------------------------------
/src/lib/shapeController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include "shapeBase.h"
23 | #include "rapidjson/document.h"
24 |
25 | #include
26 | #include
27 |
28 | namespace simplex {
29 |
30 | class Progression;
31 |
32 | class ShapeController : public ShapeBase {
33 | protected:
34 | bool enabled;
35 | double value;
36 | double multiplier;
37 | Progression* prog;
38 | public:
39 | ShapeController(const std::string &name, Progression* prog, size_t index):
40 | ShapeBase(name, index), enabled(true), value(0.0), multiplier(1.0), prog(prog) {}
41 |
42 | virtual bool sliderType() const { return true; }
43 | void clearValue(){value = 0.0; multiplier=1.0;}
44 | const double getValue() const { return value; }
45 | const double getMultiplier() const { return multiplier; }
46 | void setEnabled(bool enable){enabled = enable;}
47 | virtual void storeValue(
48 | const std::vector &values,
49 | const std::vector &posValues,
50 | const std::vector &clamped,
51 | const std::vector &inverses) = 0;
52 | void solve(std::vector &accumulator, double &maxAct) const;
53 | static bool getEnabled(const rapidjson::Value &val);
54 | };
55 |
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/src/lib/simplex.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 | #include "utils.h"
20 | #include "simplex.h"
21 |
22 | #include "rapidjson/error/en.h"
23 | #include "rapidjson/rapidjson.h"
24 |
25 | using namespace simplex;
26 |
27 | void Simplex::clearValues(){
28 | for (auto xit = sliders.begin(); xit != sliders.end(); ++xit) { xit->clearValue(); }
29 | for (auto xit = combos.begin(); xit != combos.end(); ++xit) { xit->clearValue(); }
30 | for (auto xit = floaters.begin(); xit != floaters.end(); ++xit) { xit->clearValue(); }
31 | for (auto xit = traversals.begin(); xit != traversals.end(); ++xit) { xit->clearValue(); }
32 |
33 | //for (auto &x : sliders) x.clearValue();
34 | //for (auto &x : combos) x.clearValue();
35 | //for (auto &x : floaters) x.clearValue();
36 | //for (auto &x : traversals) x.clearValue();
37 | }
38 |
39 | void Simplex::setExactSolve(bool exact){
40 | for (auto xit = combos.begin(); xit != combos.end(); ++xit) { xit->setExact(exact); }
41 | //for (auto &x : combos) x.setExact(exact);
42 | }
43 |
44 | std::vector Simplex::solve(const std::vector &vec){
45 | // The solver should simply follow this pattern:
46 | // Ask each top level thing to store its value
47 | // Ask each shape controller for its contribution to the output
48 | std::vector posVec, clamped, output;
49 | std::vector inverses;
50 | rectify(vec, posVec, clamped, inverses);
51 |
52 |
53 | for (auto xit = sliders.begin(); xit != sliders.end(); ++xit){
54 | xit->storeValue(vec, posVec, clamped, inverses);
55 | }
56 | for (auto xit = combos.begin(); xit != combos.end(); ++xit){
57 | xit->storeValue(vec, posVec, clamped, inverses);
58 | }
59 | for (auto xit = spaces.begin(); xit != spaces.end(); ++xit){
60 | xit->storeValue(vec, posVec, clamped, inverses);
61 | }
62 | for (auto xit = traversals.begin(); xit != traversals.end(); ++xit){
63 | xit->storeValue(vec, posVec, clamped, inverses);
64 | }
65 |
66 | /*
67 | for (auto &x : sliders)
68 | x.storeValue(vec, posVec, clamped, inverses);
69 | for (auto &x : combos)
70 | x.storeValue(vec, posVec, clamped, inverses);
71 | for (auto &x : spaces)
72 | x.storeValue(vec, posVec, clamped, inverses);
73 | for (auto &x : traversals)
74 | x.storeValue(vec, posVec, clamped, inverses);
75 | */
76 |
77 | output.resize(shapes.size());
78 | double maxAct = 0.0;
79 |
80 | for (auto xit = sliders.begin(); xit != sliders.end(); ++xit)
81 | xit->solve(output, maxAct);
82 | for (auto xit = combos.begin(); xit != combos.end(); ++xit)
83 | xit->solve(output, maxAct);
84 | for (auto xit = floaters.begin(); xit != floaters.end(); ++xit)
85 | xit->solve(output, maxAct);
86 | for (auto xit = traversals.begin(); xit != traversals.end(); ++xit)
87 | xit->solve(output, maxAct);
88 |
89 | /*
90 | for (auto &x : sliders)
91 | x.solve(output, maxAct);
92 | for (auto &x : combos)
93 | x.solve(output, maxAct);
94 | for (auto &x : floaters)
95 | x.solve(output, maxAct);
96 | for (auto &x : traversals)
97 | x.solve(output, maxAct);
98 | */
99 |
100 | // set the rest value properly
101 | if (!output.empty())
102 | output[0] = 1.0 - maxAct;
103 | return output;
104 | }
105 |
106 | Simplex::Simplex(const std::string &json){
107 | parseJSON(json);
108 | }
109 |
110 | Simplex::Simplex(const char *json){
111 | parseJSON(std::string(json));
112 | }
113 |
114 | bool Simplex::parseJSONversion(const rapidjson::Document &d, unsigned version){
115 | // Must have these
116 | if (!d.HasMember("shapes")) return false;
117 | if (!d.HasMember("progressions")) return false;
118 | if (!d.HasMember("sliders")) return false;
119 |
120 | const rapidjson::Value &jshapes = d["shapes"];
121 | const rapidjson::Value &jsliders = d["sliders"];
122 | const rapidjson::Value &jprogs = d["progressions"];
123 |
124 | if (!jshapes.IsArray()) return false;
125 | if (!jsliders.IsArray()) return false;
126 | if (!jprogs.IsArray()) return false;
127 |
128 | rapidjson::SizeType i;
129 | bool ret;
130 | for (i = 0; i(json.c_str());
205 |
206 | hasParseError = false;
207 | if (d.HasParseError()){
208 | hasParseError = true;
209 | parseError = std::string(rapidjson::GetParseError_En(d.GetParseError()));
210 | parseErrorOffset = d.GetErrorOffset();
211 | return false;
212 | }
213 |
214 | unsigned encoding = 1u;
215 | if (d.HasMember("encodingVersion")){
216 | const rapidjson::Value &ev = d["encodingVersion"];
217 | if (!ev.IsUint()) return false;
218 | encoding = ev.GetUint();
219 | }
220 | return parseJSONversion(d, encoding);
221 | }
222 |
223 | void Simplex::clear() {
224 | shapes.clear();
225 | progs.clear();
226 | sliders.clear();
227 | combos.clear();
228 | floaters.clear();
229 | spaces.clear();
230 | traversals.clear();
231 |
232 | built = false;
233 | loaded = false;
234 | hasParseError = false;
235 | }
236 |
237 | void Simplex::build() {
238 | spaces = TriSpace::buildSpaces(floaters);
239 | built = true;
240 | }
241 |
242 |
--------------------------------------------------------------------------------
/src/lib/simplex.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include "shape.h"
23 | #include "progression.h"
24 | #include "slider.h"
25 | #include "combo.h"
26 | #include "floater.h"
27 | #include "trispace.h"
28 | #include "traversal.h"
29 |
30 | #include "rapidjson/document.h"
31 |
32 | #include
33 | #include
34 |
35 | namespace simplex {
36 |
37 | class Simplex {
38 | private:
39 | bool exactSolve;
40 | public:
41 | std::vector shapes;
42 | std::vector progs;
43 | std::vector sliders;
44 | std::vector combos;
45 | std::vector floaters;
46 | std::vector spaces;
47 | std::vector traversals;
48 |
49 | bool built;
50 | bool loaded;
51 | bool hasParseError;
52 |
53 | std::string parseError;
54 | size_t parseErrorOffset;
55 | const size_t sliderLen() const { return sliders.size(); }
56 |
57 | Simplex():exactSolve(true), built(false), loaded(false), hasParseError(false) {};
58 | explicit Simplex(const std::string &json);
59 | explicit Simplex(const char* json);
60 |
61 | void clearValues();
62 | void clear();
63 | bool parseJSON(const std::string &json);
64 | bool parseJSONversion(const rapidjson::Document &d, unsigned version);
65 | void build();
66 |
67 | void setExactSolve(bool exact);
68 | bool getExactSolve() { return exactSolve; }
69 |
70 | std::vector solve(const std::vector &vec);
71 | };
72 |
73 | } // end namespace simplex
74 |
--------------------------------------------------------------------------------
/src/lib/slider.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 | #include "simplex.h"
20 | #include "slider.h"
21 |
22 | #include "rapidjson/document.h"
23 |
24 | #include
25 | #include
26 |
27 | using namespace simplex;
28 |
29 | bool Slider::parseJSONv1(const rapidjson::Value &val, size_t index, Simplex *simp){
30 | if (!val[0u].IsString()) return false;
31 | if (!val[1].IsInt()) return false;
32 |
33 | std::string name(val[0u].GetString()); // needs to be 0u
34 | size_t slidx = size_t(val[1].GetInt());
35 |
36 | if (slidx >= simp->progs.size()) return false;
37 | simp->sliders.push_back(Slider(name, &simp->progs[slidx], index));
38 | return true;
39 | }
40 |
41 | bool Slider::parseJSONv2(const rapidjson::Value &val, size_t index, Simplex *simp){
42 | if (!val.IsObject()) return false;
43 |
44 | CHECK_JSON_STRING(nameIt, "name", val);
45 | CHECK_JSON_INT(progIt, "prog", val);
46 |
47 | std::string name(nameIt->value.GetString());
48 | size_t slidx = size_t(progIt->value.GetInt());
49 |
50 | if (slidx >= simp->progs.size()) return false;
51 |
52 | bool enabled = getEnabled(val);
53 |
54 | simp->sliders.push_back(Slider(name, &simp->progs[slidx], index));
55 | simp->sliders.back().setEnabled(enabled);
56 | return true;
57 | }
58 |
59 | bool Slider::parseJSONv3(const rapidjson::Value &val, size_t index, Simplex *simp){
60 | return parseJSONv2(val, index, simp);
61 | }
62 |
63 |
64 |
--------------------------------------------------------------------------------
/src/lib/slider.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include "shapeController.h"
23 | #include "rapidjson/document.h"
24 |
25 | #include
26 | #include
27 |
28 | namespace simplex {
29 |
30 | class Simplex;
31 | class Progression;
32 |
33 | class Slider : public ShapeController {
34 | public:
35 | Slider(const std::string &name, Progression* prog, size_t index) : ShapeController(name, prog, index){}
36 | void storeValue(
37 | const std::vector &values,
38 | const std::vector &posValues,
39 | const std::vector &clamped,
40 | const std::vector &inverses){
41 | if (!enabled) return;
42 | this->value = values[this->index];
43 | }
44 |
45 | static bool parseJSONv1(const rapidjson::Value &val, size_t index, Simplex *simp);
46 | static bool parseJSONv2(const rapidjson::Value &val, size_t index, Simplex *simp);
47 | static bool parseJSONv3(const rapidjson::Value &val, size_t index, Simplex *simp);
48 | };
49 |
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/src/lib/traversal.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 | #include "shapeController.h"
20 | #include "slider.h"
21 | #include "combo.h"
22 | #include "traversal.h"
23 | #include "simplex.h"
24 |
25 | #include "rapidjson/document.h"
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 |
32 | using namespace simplex;
33 |
34 | Traversal::Traversal(
35 | const std::string &name, Progression* prog, size_t index,
36 | ShapeController* progressCtrl, ShapeController* multiplierCtrl, bool valueFlip, bool multiplierFlip):
37 | ShapeController(name, prog, index), exact(true){
38 |
39 | if (multiplierCtrl->sliderType()) {
40 | multState.push_back(std::make_pair((Slider*)multiplierCtrl, multiplierFlip ? -1.0 : 1.0));
41 | }
42 | else {
43 | // loop over the combos. Also, multiplier flip should *never* be negative here
44 | Combo *cmb = (Combo *) multiplierCtrl;
45 | for (auto pairIt = cmb->stateList.begin(); pairIt != cmb->stateList.end(); ++pairIt){
46 | multState.push_back(std::make_pair(pairIt->first, pairIt->second));
47 | }
48 | }
49 |
50 | if (progressCtrl->sliderType()) {
51 | progStartState.push_back(std::make_pair((Slider*)progressCtrl, 0.0));
52 | progDeltaState.push_back(std::make_pair((Slider*)progressCtrl, valueFlip ? -1.0 : 1.0));
53 | }
54 | else {
55 | // loop over the combos. Also, multiplier flip should *never* be negative here
56 | Combo *cmb = (Combo *) progressCtrl;
57 | for (auto pairIt = cmb->stateList.begin(); pairIt != cmb->stateList.end(); ++pairIt){
58 | progStartState.push_back(std::make_pair(pairIt->first, 0.0));
59 | progDeltaState.push_back(std::make_pair(pairIt->first, pairIt->second));
60 | }
61 | }
62 | }
63 |
64 | Traversal::Traversal(
65 | const std::string &name, Progression* prog, size_t index,
66 | const ComboPairs &startPairs, const ComboPairs &endPairs, ComboSolve solveType):
67 | ShapeController(name, prog, index), exact(true){
68 |
69 | std::unordered_map startSliders, endSliders;
70 | std::unordered_set allSliders;
71 |
72 | for (size_t i=0; isecond));
92 | }
93 | else if (endIt == endSliders.end()){
94 | // means slider exists in start, but not end
95 | progStartState.push_back(std::make_pair(sli, startIt->second));
96 | progDeltaState.push_back(std::make_pair(sli, -startIt->second));
97 | }
98 | else {
99 | if (startIt->second == endIt->second){
100 | // if the values are the same, add it to the multiplier state
101 | multState.push_back(std::make_pair(sli, startIt->second));
102 | }
103 | else {
104 | // if the values are different, add them to ther respective states
105 | progStartState.push_back(std::make_pair(sli, startIt->second));
106 | progDeltaState.push_back(std::make_pair(sli, endIt->second - startIt->second));
107 | }
108 | }
109 | }
110 | }
111 |
112 | void Traversal::storeValue(
113 | const std::vector &values,
114 | const std::vector &posValues,
115 | const std::vector &clamped,
116 | const std::vector &inverses) {
117 |
118 | if (!enabled) return;
119 |
120 | double mul = 0.0, val = 0.0;
121 | solveState(multState, solveType, exact, mul);
122 |
123 | std::vector vals, tars;
124 |
125 | for (size_t i = 0; i < progStartState.size(); ++i) {
126 | vals.push_back(progStartState[i].first->getValue() - progStartState[i].second);
127 | tars.push_back(progDeltaState[i].second);
128 | }
129 | solveState(vals, tars, solveType, exact, val);
130 |
131 | value = val;
132 | multiplier = mul;
133 | }
134 |
135 | bool Traversal::parseJSONv1(const rapidjson::Value &val, size_t index, Simplex *simp){
136 | return parseJSONv2(val, index, simp);
137 | }
138 |
139 | bool Traversal::parseJSONv2(const rapidjson::Value &val, size_t index, Simplex *simp){
140 | if (!val.IsObject()) return false;
141 |
142 | CHECK_JSON_STRING(nameIt, "name", val)
143 | CHECK_JSON_INT(progIt, "prog", val)
144 | CHECK_JSON_STRING(ptIt, "progressType", val)
145 | CHECK_JSON_INT(pcIt, "progressControl", val)
146 | CHECK_JSON_BOOL(pfIt, "progressFlip", val)
147 | CHECK_JSON_STRING(mtIt, "multiplierType", val)
148 | CHECK_JSON_INT(mcIt, "multiplierControl", val)
149 | CHECK_JSON_BOOL(mfIt, "multiplierFlip", val)
150 |
151 | std::string name(nameIt->value.GetString());
152 | size_t pidx = (size_t)progIt->value.GetInt();
153 | std::string pctype(ptIt->value.GetString());
154 | std::string mctype(mtIt->value.GetString());
155 | size_t pcidx = (size_t)pcIt->value.GetInt();
156 | size_t mcidx = (size_t)mcIt->value.GetInt();
157 | bool pcFlip = pfIt->value.GetBool();
158 | bool mcFlip = mfIt->value.GetBool();
159 |
160 | ShapeController *pcItem;
161 | if (!pctype.empty() && pctype[0] == 'S') {
162 | if (pcidx >= simp->sliders.size()) return false;
163 | pcItem = &simp->sliders[pcidx];
164 | }
165 | else {
166 | if (pcidx >= simp->combos.size()) return false;
167 | pcItem = &simp->combos[pcidx];
168 | }
169 |
170 | ShapeController *mcItem;
171 | if (!mctype.empty() && mctype[0] == 'S') {
172 | if (mcidx >= simp->sliders.size()) return false;
173 | mcItem = &simp->sliders[mcidx];
174 | }
175 | else {
176 | if (mcidx >= simp->combos.size()) return false;
177 | mcItem = &simp->combos[mcidx];
178 | }
179 |
180 | if (pidx >= simp->progs.size()) return false;
181 |
182 | bool enabled = getEnabled(val);
183 |
184 | simp->traversals.push_back(Traversal(name, &simp->progs[pidx], index, pcItem, mcItem, pcFlip, mcFlip));
185 | simp->traversals.back().setEnabled(enabled);
186 | return true;
187 | }
188 |
189 | bool Traversal::parseJSONv3(const rapidjson::Value &val, size_t index, Simplex *simp){
190 | if (!val.IsObject()) return false;
191 |
192 | CHECK_JSON_STRING(nameIt, "name", val)
193 | CHECK_JSON_INT(progIt, "prog", val)
194 | CHECK_JSON_ARRAY(startIt, "start", val)
195 | CHECK_JSON_ARRAY(endIt, "end", val)
196 |
197 | ComboSolve solveType = getSolveType(val);
198 |
199 | bool isFloater = false;
200 | ComboPairs startPairs, endPairs;
201 | if (!getSolvePairs(startIt->value, simp, startPairs, isFloater)) return false;
202 | if (!getSolvePairs(endIt->value, simp, endPairs, isFloater)) return false;
203 |
204 | std::string name(nameIt->value.GetString());
205 | size_t pidx = (size_t)progIt->value.GetInt();
206 | if (pidx >= simp->progs.size()) return false;
207 |
208 | bool enabled = getEnabled(val);
209 | simp->traversals.push_back(Traversal(name, &simp->progs[pidx], index, startPairs, endPairs, solveType));
210 | simp->traversals.back().setEnabled(enabled);
211 | return true;
212 | }
213 |
--------------------------------------------------------------------------------
/src/lib/traversal.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include "combo.h"
23 | #include "shapeController.h"
24 | #include "rapidjson/document.h"
25 |
26 | #include
27 | #include
28 |
29 | namespace simplex {
30 |
31 | class Progression;
32 | class Simplex;
33 | class Slider;
34 |
35 |
36 | class Traversal : public ShapeController {
37 | private:
38 | ComboPairs progStartState;
39 | ComboPairs progDeltaState;
40 | ComboPairs multState;
41 | ComboSolve solveType;
42 | bool exact;
43 | public:
44 | /*
45 | Traversal(const std::string &name, Progression* prog, size_t index,
46 | ShapeController* progressCtrl, ShapeController* multiplierCtrl, bool valueFlip, bool multiplierFlip):
47 | ShapeController(name, prog, index), progressCtrl(progressCtrl), multiplierCtrl(multiplierCtrl),
48 | valueFlip(valueFlip), multiplierFlip(multiplierFlip) {}
49 | */
50 |
51 | Traversal(const std::string &name, Progression* prog, size_t index, ShapeController* progressCtrl, ShapeController* multiplierCtrl, bool valueFlip, bool multiplierFlip);
52 | Traversal(const std::string &name, Progression* prog, size_t index, const ComboPairs &startState, const ComboPairs &endState, ComboSolve solveType);
53 |
54 | void storeValue(
55 | const std::vector &values,
56 | const std::vector &posValues,
57 | const std::vector &clamped,
58 | const std::vector &inverses);
59 | static bool parseJSONv1(const rapidjson::Value &val, size_t index, Simplex *simp);
60 | static bool parseJSONv2(const rapidjson::Value &val, size_t index, Simplex *simp);
61 | static bool parseJSONv3(const rapidjson::Value &val, size_t index, Simplex *simp);
62 | };
63 |
64 |
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/src/lib/trispace.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 | #include "trispace.h"
20 | #include "floater.h"
21 | #include "simplex.h"
22 | #include "slider.h"
23 | #include "utils.h"
24 |
25 | #include "math.h"
26 | #include "Eigen/Dense"
27 |
28 | #include // for all_of, sort
29 | #include // for accumulate
30 | #include
31 | #include
32 | #include
33 |
34 | using namespace simplex;
35 |
36 | // Check if the stateList of one floater is equal to another
37 | bool stateEq(
38 | std::vector> lhs,
39 | std::vector> rhs
40 | ){
41 | for (size_t i=0; i TriSpace::buildSpaces(std::vector &floaters){
49 | // group floaters by subspace dimension span
50 | std::vector> dimmed;
51 | for (auto fit = floaters.begin(); fit!=floaters.end(); ++fit){
52 | //for (auto &floater : floaters){
53 | auto &floater = *fit;
54 | size_t sls = floater.stateList.size();
55 | if (sls >= dimmed.size()) dimmed.resize(sls+1);
56 | dimmed[sls].push_back(&floater);
57 | }
58 |
59 | // Go through each dimension group and separate them by shared
60 | // sliders and directions
61 | std::vector spaces;
62 | for ( auto dit = dimmed.begin(); dit != dimmed.end(); ++dit){
63 | //for (auto &dim : dimmed){
64 | auto &dim = *dit;
65 | std::vector bucket;
66 | std::vector used(dim.size());
67 | for (size_t i=0; istateList, dim[j]->stateList)){
76 | used[j] = true;
77 | bucket.push_back(dim[j]);
78 | }
79 | }
80 | spaces.push_back(TriSpace(bucket));
81 | }
82 | }
83 | return spaces;
84 | }
85 |
86 | TriSpace::TriSpace(std::vector floaters):floaters(floaters){
87 | triangulate();
88 | }
89 |
90 | void TriSpace::triangulate(){
91 | std::unordered_map<
92 | std::vector,
93 | std::vector>,
94 | vectorHash
95 | > d;
96 |
97 | for ( auto fit = floaters.begin(); fit != floaters.end(); ++fit){
98 | //for (auto f : floaters){
99 | auto &f = *fit;
100 | std::vector userPoint;
101 | for (auto sit = f->stateList.begin(); sit != f->stateList.end(); ++sit){
102 | //for (auto sp : stateList){
103 | auto &sp = *sit;
104 | userPoint.push_back(sp.second);
105 | }
106 | userPoints.push_back(userPoint);
107 | std::vector> rawSimps = pointToAdjSimp(userPoint);
108 | for ( auto rit = rawSimps.begin(); rit != rawSimps.end(); ++rit){
109 | //for (auto &rawSimp : rawSimps){
110 | auto &rawSimp = *rit;
111 | d[rawSimp].push_back(userPoint);
112 | }
113 | }
114 |
115 | for (auto pit = d.begin(); pit != d.end(); ++pit){
116 | //for (auto p : d){
117 | auto p = *pit;
118 | overrideSimplices.push_back(p.first);
119 | std::vector> singleSimp;
120 | singleSimp.push_back(p.first);
121 | auto ext = splitSimps(p.second, singleSimp);
122 | for (auto uit = ext.begin(); uit != ext.end(); ++uit){
123 | //for (auto &userSimplex : ext){
124 | auto &userSimplex = *uit;
125 | std::vector newSimp;
126 | for (size_t cIdx=0; cIdx &values,
143 | const std::vector &posValues,
144 | const std::vector &clamped,
145 | const std::vector &inverses
146 | ){
147 | std::vector subInverse;
148 | std::vector vec;
149 | // All floats in a trispace share the same span
150 | // so I only need to check one of them
151 | for (auto pit = floaters[0]->stateList.begin(); pit != floaters[0]->stateList.end(); ++pit){
152 | //for (auto &p : floaters[0]->stateList) {
153 | auto &p = *pit;
154 | size_t idx = p.first->getIndex();
155 | subInverse.push_back(inverses[idx]);
156 | double cval = clamped[idx];
157 | if (isZero(cval)) return;
158 | vec.push_back(cval);
159 | }
160 | if (floaters[0]->inverted != subInverse) return;
161 |
162 | std::vector majorSimp = pointToSimp(vec);
163 | size_t c = simplexMap.count(majorSimp);
164 | if (c == 0) return;
165 |
166 | std::vector> &simps = simplexMap[majorSimp];
167 |
168 |
169 | for (auto sit = simps.begin(); sit != simps.end(); ++sit){
170 | //for (auto &simp : simps){
171 | auto &simp = *sit;
172 | std::vector> expanded;
173 | std::vector floaterCorners;
174 | // TODO: Didn't fill "expanded" properly
175 | userSimplexToCorners(simp, majorSimp, expanded, floaterCorners);
176 |
177 | std::vector b = barycentric(expanded, vec);
178 | if (std::all_of(b.begin(), b.end(), isPositive)){
179 | for (size_t i = 0; i < b.size(); ++i) {
180 | int fcIdx = floaterCorners[i];
181 | if (fcIdx != -1) {
182 | floaters[fcIdx]->value = b[i];
183 | }
184 | }
185 | break;
186 | }
187 | }
188 | }
189 |
190 | std::vector> TriSpace::pointToAdjSimp(
191 | const std::vector &pt,
192 | double eps
193 | ) {
194 | //Search for simplices that are near the point
195 | //This allows for splitting the simplex, or snapping a
196 | //point to a nearby progression
197 |
198 | // Point, OrderedValues, CurrentSimplex, Output
199 |
200 | std::vector > out;
201 | std::vector rn, simp;
202 | rn.resize(pt.size());
203 | for (int i=0; i &point,
213 | const std::vector &oVals,
214 | const std::vector &simp,
215 | std::vector > &out,
216 | double eps
217 | ) const {
218 | if (point.empty()){
219 | out.push_back(simp);
220 | return;
221 | }
222 |
223 | double maxabs = fabs(point[0]);
224 | for (size_t i=0; i maxabs){
227 | maxabs = aa;
228 | }
229 | }
230 |
231 | std::vector mxs;
232 | for (size_t i=0; i subpoint;
239 | std::vector subvals, nSimp;
240 | bool mvZero = isZero(maxabs);
241 |
242 | for (size_t i=0; i searchDirection;
244 | // zero is both positive and negative
245 | // so I need to do both directions
246 | size_t mx = mxs[i];
247 | if (mvZero){
248 | searchDirection.push_back(-1);
249 | searchDirection.push_back(1);
250 | }
251 | else {
252 | int p = (isPositive(point[mx])) ? 1 : -1;
253 | searchDirection.push_back(p);
254 | }
255 |
256 | //for (int direction : searchDirection){
257 | for (auto dit = searchDirection.begin(); dit != searchDirection.end(); ++dit) {
258 | int direction = *dit;
259 | int newval = (oVals[mx] + 1) * direction;
260 |
261 | // Copy
262 | nSimp = simp;
263 | subpoint = point;
264 | subvals = oVals;
265 |
266 | nSimp.insert(nSimp.end(), newval);
267 | subpoint.erase(subpoint.begin()+mx);
268 | subvals.erase(subvals.begin()+mx);
269 | TriSpace::rec(subpoint, subvals, nSimp, out, eps);
270 | }
271 | }
272 | }
273 |
274 | std::vector > TriSpace::simplexToCorners(
275 | const std::vector &simplex
276 | ) const {
277 | std::vector currVec(simplex.size() - 1, 0.0);
278 | std::vector > out;
279 | for (size_t i = 0; i 0) ? s : -s;
286 | double val = (s > 0) ? 1.0 : -1.0;
287 |
288 | if (idx >= simplex.size()) {
289 | idx = idx - int(simplex.size());
290 | out.push_back(this->userPoints[idx]);
291 | }
292 | else {
293 | currVec[idx - 1] = val;
294 | out.push_back(currVec);
295 | }
296 | }
297 | return out;
298 | }
299 |
300 | std::vector > > TriSpace::splitSimps(
301 | const std::vector > &pts,
302 | const std::vector > &simps
303 | ) const {
304 | std::vector > > out, tmpList;
305 | for (size_t i = 0; i &p = pts[i];
311 | tmpList.clear();
312 | for (size_t j = 0; j bary = barycentric(out[j], p);
314 | if (std::all_of(bary.begin(), bary.end(), isPositive)) {
315 | for (size_t k = 0; k> ns = out[j];
319 | ns[k] = p;
320 | tmpList.push_back(std::move(ns));
321 | }
322 | }
323 | }
324 | else {
325 | tmpList.push_back(out[j]);
326 | }
327 | }
328 | out = tmpList;
329 | }
330 | return out;
331 | }
332 |
333 | std::vector TriSpace::barycentric(
334 | const std::vector> &simplex,
335 | const std::vector &p
336 | ) const {
337 |
338 | std::vector last = simplex.back();
339 |
340 | // lastVec = (p - last)
341 | Eigen::VectorXd lastVec(p.size());
342 | for (size_t i=0; i out(&outArray[0],&outArray[p.size()]);
359 | double sum = accumulate(out.begin(), out.end(), 0.0);
360 | out.push_back(1.0 - sum); // 1-sum = missing value
361 | return out;
362 | }
363 |
364 | std::vector TriSpace::pointToSimp(const std::vector &pt) {
365 | /*
366 | Each simplex can be represented as a permutation of [(+-)(i+1) for i in range(len(dim))]
367 | So I will encode these values by the pos/neg direction along a dimension number.
368 | We always start at 0, so that makes [0,-2,4,1,-3] a valid encoding
369 |
370 | The resultant simplex is called a "Schlafli Orthoscheme"
371 | */
372 | std::vector > abspt;
373 | double v;
374 | int idx, i, n;
375 | for (i=0; i &a, const std::pair &b) {
383 | return a.second < b.second;
384 | }
385 | );
386 |
387 | std::vector out;
388 | out.push_back(0);
389 | for (i=int(abspt.size()); i>0; --i){
390 | out.push_back(abspt[i-1].first);
391 | }
392 | return out;
393 | }
394 |
395 | void TriSpace::userSimplexToCorners(
396 | const std::vector &simplex,
397 | const std::vector &original,
398 | std::vector> &out,
399 | std::vector &floaterCorners // TODO
400 | ) const{
401 |
402 | std::vector currVec (simplex.size()-1, 0.0);
403 | for (size_t i=0; i 0)? s : -s;
413 |
414 | // get the original idx
415 | int oidx = (os > 0)? os : -os;
416 | double val = (os > 0)? 1.0 : -1.0;
417 |
418 | if (oidx != 0){
419 | // keep track of where we *would* be normally
420 | // unless we're replacing the first item
421 | currVec[oidx-1] = val;
422 | }
423 |
424 | // if the user idx is too high
425 | if (idx >= simplex.size()){
426 | // grab a user point
427 | idx = idx - int(simplex.size());
428 | out.push_back(this->userPoints[idx]);
429 | floaterCorners.push_back(idx);
430 | }
431 | else {
432 | // get the currVec
433 | out.push_back(currVec);
434 | floaterCorners.push_back(-1);
435 | }
436 | }
437 | }
438 |
439 |
--------------------------------------------------------------------------------
/src/lib/trispace.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include "enums.h"
23 | #include "utils.h"
24 | #include
25 | #include
26 |
27 | namespace simplex {
28 |
29 | class Floater;
30 |
31 | class TriSpace {
32 | private:
33 | // Correlates the auto-generated simplex with the user-created simplices
34 | // resulting from the splitting procedure
35 | std::unordered_map, std::vector>, vectorHash> simplexMap;
36 | std::vector> userPoints;
37 | std::vector> overrideSimplices;
38 |
39 | std::vector floaters;
40 | std::vector barycentric(const std::vector> &simplex, const std::vector &p) const;
41 | //static std::vector> simplexToCorners(const std::vector &simplex);
42 | std::vector pointToSimp(const std::vector &pt);
43 | std::vector> pointToAdjSimp(const std::vector &pt, double eps=0.01);
44 | void triangulate(); // convenience function for separating the data access from the actual math
45 | // Code to split a list of simplices by a list of points, only used in triangulate()
46 | std::vector>> splitSimps(const std::vector> &pts, const std::vector> &simps) const;
47 | std::vector > simplexToCorners(const std::vector &simplex) const;
48 | void rec(const std::vector &point, const std::vector &oVals, const std::vector &simp, std::vector > &out, double eps) const;
49 |
50 | // break down the given simplex encoding to a list of corner points for the barycentric solver and
51 | // a correlation of the point index to the floater index (or size_t_MAX if invalid)
52 | void userSimplexToCorners(
53 | const std::vector &simplex,
54 | const std::vector &original,
55 | std::vector> &out,
56 | std::vector &floaterCorners
57 | ) const;
58 |
59 | public:
60 | // Take the non-related floaters and group them by shared span and orthant
61 | static std::vector buildSpaces(std::vector &floaters);
62 | TriSpace(std::vector floaters);
63 | void storeValue(
64 | const std::vector &values,
65 | const std::vector &posValues,
66 | const std::vector &clamped,
67 | const std::vector &inverses);
68 | };
69 |
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/src/lib/utils.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 | #include "utils.h"
22 | #include "math.h"
23 | #include
24 | #include
25 | #include
26 |
27 | namespace simplex{
28 |
29 | void rectify(
30 | const std::vector &rawVec,
31 | std::vector &values,
32 | std::vector &clamped,
33 | std::vector &inverses
34 | ){
35 | // Rectifying just makes everything positive, keeps track of the inversion, and applies clamping
36 | values.resize(rawVec.size());
37 | clamped.resize(rawVec.size());
38 | inverses.resize(rawVec.size());
39 | for (size_t i=0; i MAXVAL) ? MAXVAL : v;
47 | }
48 | }
49 |
50 | double doSoftMin(double X, double Y) {
51 | if (isZero(X) || isZero(Y)) return 0.0;
52 | if (X < Y) std::swap(X, Y);
53 |
54 | double n = 4.0;
55 | double h = 0.025;
56 | double p = 2.0;
57 | double q = 1.0 / p;
58 |
59 | double d = 2.0 * (pow(1.0 + h, q) - pow(h, q));
60 | double s = pow(h, q);
61 | double z = pow(pow(X, p) + h, q) + pow(pow(Y, p) + h, q) - pow(pow(X - Y, p) + h, q);
62 | return (z - s) / d;
63 | }
64 | } // namespace simplex
65 |
--------------------------------------------------------------------------------
/src/lib/utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 | #include // for hash
24 | #include "rapidjson/document.h"
25 | #include "math.h"
26 |
27 | #define CHECK_JSON_STRING(jsIt, jsName, jsVal) \
28 | auto (jsIt) = (jsVal).FindMember(jsName); \
29 | if ((jsIt) == (jsVal).MemberEnd()) return false; \
30 | if (!(jsIt)->value.IsString()) return false;
31 |
32 | #define CHECK_JSON_BOOL(jsIt, jsName, jsVal) \
33 | auto (jsIt) = (jsVal).FindMember(jsName); \
34 | if ((jsIt) == (jsVal).MemberEnd()) return false; \
35 | if (!(jsIt)->value.IsBool()) return false;
36 |
37 | #define CHECK_JSON_INT(jsIt, jsName, jsVal) \
38 | auto (jsIt) = (jsVal).FindMember(jsName); \
39 | if ((jsIt) == (jsVal).MemberEnd()) return false; \
40 | if (!(jsIt)->value.IsInt()) return false;
41 |
42 | #define CHECK_JSON_ARRAY(jsIt, jsName, jsVal) \
43 | auto (jsIt) = (jsVal).FindMember(jsName); \
44 | if ((jsIt) == (jsVal).MemberEnd()) return false; \
45 | if (!(jsIt)->value.IsArray()) return false;
46 |
47 |
48 | namespace simplex {
49 | const double EPS = 1e-6;
50 | const int ULPS = 4;
51 | const double MAXVAL = 1.0; // max clamping value
52 |
53 | inline bool floatEQ(const double A, const double B, const double eps) {
54 | // from https://randomascii.wordpress.com/2012/01/11/tricks-with-the-floating-point-format
55 | // Check if the numbers are really close -- needed
56 | // when comparing numbers near zero.
57 | double absDiff = fabs(A - B);
58 | if (absDiff <= eps)
59 | return true;
60 | return false;
61 | }
62 |
63 | inline bool isZero(const double a) { return floatEQ(a, 0.0, EPS); }
64 | inline bool isPositive(const double a) { return a > -EPS; }
65 | inline bool isNegative(const double a) { return a < EPS; }
66 |
67 | void rectify(
68 | const std::vector &rawVec,
69 | std::vector &values,
70 | std::vector &clamped,
71 | std::vector &inverses
72 | );
73 |
74 | double doSoftMin(double X, double Y);
75 |
76 | template
77 | struct vectorHash {
78 | size_t operator()(const std::vector & val) const {
79 | // this is the python tuple hashing algorithm
80 | size_t value = 0x345678;
81 | size_t vSize = val.size();
82 | std::hash iHash;
83 | for (auto i = val.begin(); i != val.end(); ++i) {
84 | value = (1000003 * value) ^ iHash(*i);
85 | value = value ^ vSize;
86 | }
87 | return value;
88 | }
89 | };
90 |
91 | } // namespace simplex
92 |
--------------------------------------------------------------------------------
/src/maya/pluginMain.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #include "simplex_mayaNode.h"
21 | #include
22 | #include
23 | #include
24 |
25 | MStatus initializePlugin( MObject obj )
26 | {
27 | MStatus status;
28 | MFnPlugin plugin( obj, "", "2016", "Any");
29 |
30 | status = plugin.registerNode( "simplex_maya", simplex_maya::id, simplex_maya::creator,
31 | simplex_maya::initialize );
32 | if (!status) {
33 | status.perror("registerNode");
34 | return status;
35 | }
36 |
37 | return status;
38 | }
39 |
40 | MStatus uninitializePlugin( MObject obj)
41 | {
42 | MStatus status;
43 | MFnPlugin plugin( obj );
44 |
45 | status = plugin.deregisterNode( simplex_maya::id );
46 | if (!status) {
47 | status.perror("deregisterNode");
48 | return status;
49 | }
50 |
51 | return status;
52 | }
53 |
--------------------------------------------------------------------------------
/src/maya/simplex_mayaNode.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #include "simplex_mayaNode.h"
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #define CHECKSTAT(s) if (!(s)) { (s).perror("attributeAffects"); return (s);}
29 |
30 | #ifdef __linux__
31 | typedef unsigned int UINT;
32 | #endif
33 |
34 | MTypeId simplex_maya::id(0x001226C8);
35 |
36 | // Attribute list
37 | MObject simplex_maya::aSliders;
38 | MObject simplex_maya::aWeights;
39 | MObject simplex_maya::aDefinition;
40 | MObject simplex_maya::aMinorUpdate;
41 | MObject simplex_maya::aExactSolve;
42 |
43 |
44 | simplex_maya::simplex_maya() {
45 | this->sPointer = new simplex::Simplex();
46 | }
47 | simplex_maya::~simplex_maya() {
48 | delete this->sPointer;
49 | }
50 |
51 | MStatus simplex_maya::compute(const MPlug& plug, MDataBlock& data) {
52 | MStatus status;
53 | if( plug == aWeights ) {
54 | MArrayDataHandle inputData = data.inputArrayValue(aSliders, &status);
55 | CHECKSTAT(status);
56 |
57 | std::vector inVec;
58 | inVec.resize(inputData.elementCount());
59 |
60 | // Read the input value from the handle.
61 | for (UINT physIdx = 0; physIdx < inputData.elementCount(); ++physIdx){
62 | inputData.jumpToArrayElement(physIdx);
63 | auto valueHandle = inputData.inputValue(&status);
64 | CHECKSTAT(status);
65 | UINT trueIdx = inputData.elementIndex();
66 | if (trueIdx >= inVec.size()){
67 | inVec.resize(trueIdx+1);
68 | }
69 | inVec[trueIdx] = valueHandle.asDouble();
70 | }
71 |
72 | if (!simplexIsValid || !this->sPointer->loaded){
73 | MDataHandle jsonData = data.inputValue(aDefinition, &status);
74 | CHECKSTAT(status);
75 | MString ss = jsonData.asString();
76 | std::string sss(ss.asChar(), ss.length());
77 | this->sPointer->clear();
78 | this->sPointer->parseJSON(sss);
79 | this->sPointer->build();
80 |
81 | simplexIsValid = true;
82 | if (this->sPointer->hasParseError){
83 | cerr << "JSON PARSE ERROR: " << this->sPointer->parseError <<
84 | " \n At offset: " << std::to_string(this->sPointer->parseErrorOffset) << "\n";
85 | return MS::kFailure;
86 | }
87 | }
88 |
89 | if (this->sPointer->loaded){
90 | MDataHandle exactSolve = data.inputValue(aExactSolve, &status);
91 | CHECKSTAT(status);
92 | this->sPointer->setExactSolve(exactSolve.asBool());
93 | }
94 |
95 | inVec.resize(this->sPointer->sliderLen());
96 |
97 | if (!cacheIsValid){
98 | cacheIsValid = true;
99 | this->sPointer->clearValues();
100 | cache = this->sPointer->solve(inVec);
101 | }
102 |
103 | // Set the output weights
104 | MArrayDataHandle outputArrayHandle = data.outputArrayValue(simplex_maya::aWeights, &status);
105 | CHECKSTAT(status);
106 | for (UINT physIdx = 0; physIdx < outputArrayHandle.elementCount(); ++physIdx){
107 | outputArrayHandle.jumpToArrayElement(physIdx);
108 | UINT trueIdx = outputArrayHandle.elementIndex();
109 | auto outHandle = outputArrayHandle.outputValue(&status);
110 | CHECKSTAT(status);
111 | if (trueIdx < cache.size()) {
112 | // because the cache size can change
113 | outHandle.setDouble(cache[trueIdx]);
114 | }
115 | }
116 |
117 | outputArrayHandle.setAllClean();
118 | data.setClean(plug);
119 | }
120 | else {
121 | return MS::kUnknownParameter;
122 | }
123 |
124 | return MS::kSuccess;
125 | }
126 |
127 | MStatus simplex_maya::preEvaluation(const MDGContext& context, const MEvaluationNode& evaluationNode){
128 | MStatus status;
129 | if (context.isNormal()){
130 | if (evaluationNode.dirtyPlugExists(aDefinition, &status) && status){
131 | this->simplexIsValid = false;
132 | this->cacheIsValid = false;
133 | }
134 | if (evaluationNode.dirtyPlugExists(aSliders, &status) && status){
135 | this->cacheIsValid = false;
136 | }
137 | if (evaluationNode.dirtyPlugExists(aExactSolve, &status) && status){
138 | this->cacheIsValid = false;
139 | }
140 | }
141 | else {
142 | return MS::kFailure;
143 | }
144 | return MS::kSuccess;
145 | }
146 |
147 | MStatus simplex_maya::setDependentsDirty(const MPlug& plug, MPlugArray& plugArray){
148 | if (plug == aDefinition){
149 | this->simplexIsValid = false;
150 | this->cacheIsValid = false;
151 | }
152 | if (plug == aSliders){
153 | this->cacheIsValid = false;
154 | }
155 | if (plug == aExactSolve){
156 | this->cacheIsValid = false;
157 | }
158 | return MPxNode::setDependentsDirty(plug, plugArray);
159 | }
160 |
161 | void* simplex_maya::creator(){
162 | return new simplex_maya();
163 | }
164 |
165 | MStatus simplex_maya::initialize(){
166 | MFnNumericAttribute nAttr;
167 | MFnTypedAttribute tAttr;
168 | MFnStringData sData;
169 | MStatus status, status2;
170 |
171 | // Input sliders
172 | simplex_maya::aMinorUpdate = nAttr.create("minorUpdate", "mu", MFnNumericData::kBoolean, false, &status);
173 | CHECKSTAT(status);
174 | nAttr.setKeyable(false);
175 | nAttr.setReadable(true);
176 | nAttr.setWritable(true);
177 | status = simplex_maya::addAttribute(simplex_maya::aMinorUpdate);
178 | CHECKSTAT(status);
179 |
180 | simplex_maya::aExactSolve = nAttr.create("exactSolve", "es", MFnNumericData::kBoolean, true, &status);
181 | CHECKSTAT(status);
182 | nAttr.setKeyable(false);
183 | nAttr.setReadable(true);
184 | nAttr.setWritable(true);
185 | status = simplex_maya::addAttribute(simplex_maya::aExactSolve);
186 | CHECKSTAT(status);
187 |
188 | simplex_maya::aDefinition = tAttr.create("definition", "d", MFnData::kString, sData.create(&status2), &status);
189 | CHECKSTAT(status);
190 | CHECKSTAT(status2);
191 | tAttr.setStorable(true);
192 | tAttr.setKeyable(true);
193 | status = simplex_maya::addAttribute(simplex_maya::aDefinition);
194 | CHECKSTAT(status);
195 |
196 | // Input sliders
197 | simplex_maya::aSliders = nAttr.create("sliders", "s", MFnNumericData::kDouble, 0.0, &status);
198 | CHECKSTAT(status);
199 | nAttr.setKeyable(true);
200 | nAttr.setReadable(false);
201 | nAttr.setWritable(true);
202 | nAttr.setArray(true);
203 | nAttr.setUsesArrayDataBuilder(true);
204 | status = simplex_maya::addAttribute(simplex_maya::aSliders);
205 | CHECKSTAT(status);
206 |
207 | // Output weights
208 | simplex_maya::aWeights = nAttr.create("weights", "w", MFnNumericData::kDouble, 0.0, &status);
209 | CHECKSTAT(status);
210 | nAttr.setStorable(false);
211 | nAttr.setReadable(true);
212 | nAttr.setWritable(false);
213 | nAttr.setArray(true);
214 | nAttr.setUsesArrayDataBuilder(true);
215 | status = simplex_maya::addAttribute(simplex_maya::aWeights);
216 | CHECKSTAT(status);
217 |
218 | // Set data dependencies
219 | status = attributeAffects(aSliders, aWeights);
220 | CHECKSTAT(status);
221 | status = attributeAffects(aDefinition, aWeights);
222 | CHECKSTAT(status);
223 |
224 | return MS::kSuccess;
225 | }
226 |
227 |
--------------------------------------------------------------------------------
/src/maya/simplex_mayaNode.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2016, Blur Studio
3 |
4 | This file is part of Simplex.
5 |
6 | Simplex is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Simplex is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with Simplex. If not, see .
18 | */
19 |
20 | #pragma once
21 |
22 | #include
23 |
24 | #include
25 | #include
26 | #include
27 | #include