├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── ExtraFunctions.cpp ├── ExtraFunctions.h ├── FileDialog.h ├── InterpolateTraits.h ├── LICENSE ├── MoebiusCodeDemoScreen.png ├── PrescribeEdgeJumps.h ├── QuadConstSolver.h ├── README.md ├── UnitSphereMoebiusTraits.h ├── cmake ├── FindLIBIGL.cmake ├── libhedra.cmake └── libigl.cmake └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | build/CMakeCache.txt 2 | build/CMakeFiles/3.5.2/CMakeCCompiler.cmake 3 | build/CMakeFiles/3.5.2/CMakeCXXCompiler.cmake 4 | build/CMakeFiles/3.5.2/CMakeDetermineCompilerABI_C.bin 5 | build/CMakeFiles/3.5.2/CMakeDetermineCompilerABI_CXX.bin 6 | build/CMakeFiles/3.5.2/CMakeSystem.cmake 7 | build/CMakeFiles/3.5.2/CompilerIdC/CMakeCCompilerId.c 8 | build/CMakeFiles/3.5.2/CompilerIdC/a.out 9 | build/CMakeFiles/3.5.2/CompilerIdCXX/CMakeCXXCompilerId.cpp 10 | build/CMakeFiles/3.5.2/CompilerIdCXX/a.out 11 | build/CMakeFiles/CMakeDirectoryInformation.cmake 12 | build/CMakeFiles/CMakeOutput.log 13 | build/CMakeFiles/CMakeRuleHashes.txt 14 | build/CMakeFiles/Makefile.cmake 15 | build/CMakeFiles/Makefile2 16 | build/CMakeFiles/MoebiusDeform_bin.dir/CXX.includecache 17 | build/CMakeFiles/MoebiusDeform_bin.dir/Deform2D.cpp.o 18 | build/CMakeFiles/MoebiusDeform_bin.dir/DependInfo.cmake 19 | build/CMakeFiles/MoebiusDeform_bin.dir/build.make 20 | build/CMakeFiles/MoebiusDeform_bin.dir/cmake_clean.cmake 21 | build/CMakeFiles/MoebiusDeform_bin.dir/depend.internal 22 | build/CMakeFiles/MoebiusDeform_bin.dir/depend.make 23 | build/CMakeFiles/MoebiusDeform_bin.dir/flags.make 24 | build/CMakeFiles/MoebiusDeform_bin.dir/link.txt 25 | build/CMakeFiles/MoebiusDeform_bin.dir/progress.make 26 | build/CMakeFiles/Progress/10 27 | build/CMakeFiles/Progress/11 28 | build/CMakeFiles/Progress/12 29 | build/CMakeFiles/Progress/13 30 | build/CMakeFiles/Progress/14 31 | build/CMakeFiles/Progress/15 32 | build/CMakeFiles/Progress/16 33 | build/CMakeFiles/Progress/17 34 | build/CMakeFiles/Progress/18 35 | build/CMakeFiles/Progress/19 36 | build/CMakeFiles/Progress/2 37 | build/CMakeFiles/Progress/20 38 | build/CMakeFiles/Progress/21 39 | build/CMakeFiles/Progress/22 40 | build/CMakeFiles/Progress/23 41 | build/CMakeFiles/Progress/24 42 | build/CMakeFiles/Progress/25 43 | build/CMakeFiles/Progress/26 44 | build/CMakeFiles/Progress/27 45 | build/CMakeFiles/Progress/28 46 | build/CMakeFiles/Progress/29 47 | build/CMakeFiles/Progress/30 48 | build/CMakeFiles/Progress/31 49 | build/CMakeFiles/Progress/32 50 | build/CMakeFiles/Progress/33 51 | build/CMakeFiles/Progress/34 52 | build/CMakeFiles/Progress/35 53 | build/CMakeFiles/Progress/36 54 | build/CMakeFiles/Progress/37 55 | build/CMakeFiles/Progress/38 56 | build/CMakeFiles/Progress/39 57 | build/CMakeFiles/Progress/40 58 | build/CMakeFiles/Progress/41 59 | build/CMakeFiles/Progress/42 60 | build/CMakeFiles/Progress/43 61 | build/CMakeFiles/Progress/44 62 | build/CMakeFiles/Progress/45 63 | build/CMakeFiles/Progress/46 64 | build/CMakeFiles/Progress/47 65 | build/CMakeFiles/Progress/48 66 | build/CMakeFiles/Progress/49 67 | build/CMakeFiles/Progress/50 68 | build/CMakeFiles/Progress/51 69 | build/CMakeFiles/Progress/52 70 | build/CMakeFiles/Progress/53 71 | build/CMakeFiles/Progress/54 72 | build/CMakeFiles/Progress/7 73 | build/CMakeFiles/Progress/8 74 | build/CMakeFiles/Progress/count.txt 75 | build/CMakeFiles/TargetDirectories.txt 76 | build/CMakeFiles/cmake.check_cache 77 | build/CMakeFiles/feature_tests.bin 78 | build/CMakeFiles/feature_tests.c 79 | build/CMakeFiles/feature_tests.cxx 80 | build/CMakeFiles/progress.marks 81 | build/Makefile 82 | build/cmake_install.cmake 83 | build/libigl/CMakeFiles/CMakeDirectoryInformation.cmake 84 | build/libigl/CMakeFiles/progress.marks 85 | build/libigl/Makefile 86 | build/libigl/cmake_install.cmake 87 | build/libigl/nanogui/CMakeFiles/CMakeDirectoryInformation.cmake 88 | build/libigl/nanogui/CMakeFiles/bin2c.dir/C.includecache 89 | build/libigl/nanogui/CMakeFiles/bin2c.dir/DependInfo.cmake 90 | build/libigl/nanogui/CMakeFiles/bin2c.dir/build.make 91 | build/libigl/nanogui/CMakeFiles/bin2c.dir/cmake_clean.cmake 92 | build/libigl/nanogui/CMakeFiles/bin2c.dir/depend.internal 93 | build/libigl/nanogui/CMakeFiles/bin2c.dir/depend.make 94 | build/libigl/nanogui/CMakeFiles/bin2c.dir/flags.make 95 | build/libigl/nanogui/CMakeFiles/bin2c.dir/link.txt 96 | build/libigl/nanogui/CMakeFiles/bin2c.dir/progress.make 97 | build/libigl/nanogui/CMakeFiles/bin2c.dir/resources/bin2c.c.o 98 | build/libigl/nanogui/CMakeFiles/nanogui.dir/C.includecache 99 | build/libigl/nanogui/CMakeFiles/nanogui.dir/CXX.includecache 100 | build/libigl/nanogui/CMakeFiles/nanogui.dir/DependInfo.cmake 101 | build/libigl/nanogui/CMakeFiles/nanogui.dir/build.make 102 | build/libigl/nanogui/CMakeFiles/nanogui.dir/cmake_clean.cmake 103 | build/libigl/nanogui/CMakeFiles/nanogui.dir/cmake_clean_target.cmake 104 | build/libigl/nanogui/CMakeFiles/nanogui.dir/depend.internal 105 | build/libigl/nanogui/CMakeFiles/nanogui.dir/depend.make 106 | build/libigl/nanogui/CMakeFiles/nanogui.dir/ext/nanovg/src/nanovg.c.o 107 | build/libigl/nanogui/CMakeFiles/nanogui.dir/flags.make 108 | build/libigl/nanogui/CMakeFiles/nanogui.dir/link.txt 109 | build/libigl/nanogui/CMakeFiles/nanogui.dir/nanogui_resources.cpp.o 110 | build/libigl/nanogui/CMakeFiles/nanogui.dir/progress.make 111 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/button.cpp.o 112 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/checkbox.cpp.o 113 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/colorpicker.cpp.o 114 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/colorwheel.cpp.o 115 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/combobox.cpp.o 116 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/common.cpp.o 117 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/darwin.mm.o 118 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/glutil.cpp.o 119 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/graph.cpp.o 120 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/imagepanel.cpp.o 121 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/imageview.cpp.o 122 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/label.cpp.o 123 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/layout.cpp.o 124 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/messagedialog.cpp.o 125 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/popup.cpp.o 126 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/popupbutton.cpp.o 127 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/progressbar.cpp.o 128 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/screen.cpp.o 129 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/serializer.cpp.o 130 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/slider.cpp.o 131 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/stackedwidget.cpp.o 132 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/tabheader.cpp.o 133 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/tabwidget.cpp.o 134 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/textbox.cpp.o 135 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/theme.cpp.o 136 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/vscrollpanel.cpp.o 137 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/widget.cpp.o 138 | build/libigl/nanogui/CMakeFiles/nanogui.dir/src/window.cpp.o 139 | build/libigl/nanogui/CMakeFiles/progress.marks 140 | build/libigl/nanogui/Makefile 141 | build/libigl/nanogui/bin2c 142 | build/libigl/nanogui/cmake_install.cmake 143 | build/libigl/nanogui/ext_build/glfw/CMakeFiles/CMakeDirectoryInformation.cmake 144 | build/libigl/nanogui/ext_build/glfw/CMakeFiles/progress.marks 145 | build/libigl/nanogui/ext_build/glfw/Makefile 146 | build/libigl/nanogui/ext_build/glfw/cmake_install.cmake 147 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/CMakeDirectoryInformation.cmake 148 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw.dir/DependInfo.cmake 149 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw.dir/build.make 150 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw.dir/cmake_clean.cmake 151 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw.dir/cmake_clean_target.cmake 152 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw.dir/depend.make 153 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw.dir/flags.make 154 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw.dir/link.txt 155 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw.dir/progress.make 156 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/C.includecache 157 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/DependInfo.cmake 158 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/build.make 159 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/cmake_clean.cmake 160 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/cocoa_init.m.o 161 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/cocoa_joystick.m.o 162 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/cocoa_monitor.m.o 163 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/cocoa_time.c.o 164 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/cocoa_window.m.o 165 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/context.c.o 166 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/depend.internal 167 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/depend.make 168 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/flags.make 169 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/init.c.o 170 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/input.c.o 171 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/monitor.c.o 172 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/nsgl_context.m.o 173 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/posix_tls.c.o 174 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/progress.make 175 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/vulkan.c.o 176 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw_objects.dir/window.c.o 177 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/progress.marks 178 | build/libigl/nanogui/ext_build/glfw/src/Makefile 179 | build/libigl/nanogui/ext_build/glfw/src/cmake_install.cmake 180 | build/libigl/nanogui/ext_build/glfw/src/glfw3.pc 181 | build/libigl/nanogui/ext_build/glfw/src/glfw3Config.cmake 182 | build/libigl/nanogui/ext_build/glfw/src/glfw3ConfigVersion.cmake 183 | build/libigl/nanogui/ext_build/glfw/src/glfw_config.h 184 | build/libigl/nanogui/libnanogui.a 185 | build/libigl/nanogui/nanogui_resources.cpp 186 | build/libigl/nanogui/nanogui_resources.h 187 | build/CMakeFiles/MoebiusDeform_bin.dir/Deform3D.cpp.o 188 | build/CMakeFiles/MoebiusDeform_bin.dir/ExtraFunctions.cpp.o 189 | build/CMakeFiles/MoebiusDeform_bin.dir/QuaternionOps.cpp.o 190 | build/CMakeFiles/MoebiusDeform_bin.dir/main.cpp.o 191 | build/MoebiusDeform_bin 192 | build/libigl/nanogui/ext_build/glfw/src/CMakeFiles/glfw.dir/depend.internal 193 | build/libigl/nanogui/ext_build/glfw/src/libglfw3.a 194 | build/CMakeFiles/Progress/1 195 | build/CMakeFiles/Progress/6 196 | build/CMakeFiles/Progress/9 197 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/libhedra"] 2 | path = external/libhedra 3 | url = https://github.com/avaxman/libhedra.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(MoebiusDeform) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") 7 | message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") 8 | 9 | ### conditionally compile certain modules depending on libraries found on the system 10 | list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 11 | 12 | ### libIGL options: 13 | option(LIBIGL_EMBREE "Build target igl::embree" ON) 14 | option(LIBIGL_GLFW "Build target igl::glfw" ON) 15 | option(LIBIGL_IMGUI "Build target igl::imgui" ON) 16 | option(LIBIGL_OPENGL "Build target igl::opengl" ON) 17 | option(LIBIGL_PNG "Build target igl::png" ON) 18 | ### set(LIBIGL_WITH_PNG CACHE BOOL ON) 19 | 20 | ### Adding libIGL and Directional: choose the path to your local copy 21 | include(libigl) 22 | include(libhedra) 23 | find_package(Ceres REQUIRED) 24 | include_directories(${CERES_INCLUDE_DIRS}) 25 | 26 | ### Output directories 27 | if(MSVC) 28 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}) 29 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}) 30 | else() 31 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../") 32 | endif() 33 | 34 | 35 | 36 | message("libhedra includes: ${LIBHEDRA_INCLUDE_DIRS}") 37 | 38 | 39 | # Add your project files 40 | FILE(GLOB SRCFILES *.cpp *.h) 41 | add_executable(${PROJECT_NAME}_bin ${SRCFILES}) 42 | target_link_libraries(${PROJECT_NAME}_bin PUBLIC igl::core igl::glfw igl::opengl ${CERES_LIBRARIES}) 43 | -------------------------------------------------------------------------------- /ExtraFunctions.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ExtraFunctions.cpp 3 | // testigl 4 | // 5 | // Created by Amir Vaxman on 18/12/14. 6 | // Copyright (c) 2014 Amir Vaxman. All rights reserved. 7 | // 8 | 9 | #include "ExtraFunctions.h" 10 | #include 11 | 12 | 13 | using namespace Eigen; 14 | using namespace std; 15 | 16 | typedef std::complex Complex; 17 | 18 | void GetComplexMobiusCoeffs(Complex& a, Complex& b, Complex& c, Complex& d, const Vector3cd& z, const Vector3cd& w) 19 | { 20 | Vector3cd zw=z.cwiseProduct(w); 21 | Vector3cd ones=Vector3cd::Ones(); 22 | Matrix3cd amat,bmat,cmat,dmat; 23 | amat.col(0)=zw; amat.col(1)=w; amat.col(2)=ones; 24 | bmat.col(0)=zw; bmat.col(1)=z; bmat.col(2)=w; 25 | cmat.col(0)=z; cmat.col(1)=w; cmat.col(2)=ones; 26 | dmat.col(0)=zw; dmat.col(1)=z; dmat.col(2)=ones; 27 | 28 | a=amat.determinant(); 29 | b=bmat.determinant(); 30 | c=cmat.determinant(); 31 | d=dmat.determinant(); 32 | 33 | Complex TotalDet=a*d-b*c; 34 | Complex Sign=(real(a)>0 ? 1.0 : -1.0); 35 | a/=sqrt(TotalDet)*Sign; 36 | b/=sqrt(TotalDet)*Sign; 37 | c/=sqrt(TotalDet)*Sign; 38 | d/=sqrt(TotalDet)*Sign; 39 | 40 | } 41 | 42 | 43 | Vector2cd GetSingleMobius(const VectorXcd& OrigVc, const VectorXcd& X) 44 | { 45 | 46 | //estimating target global mobius transformation 47 | MatrixXcd MobMat(X.rows(),2); 48 | MobMat.col(0)=OrigVc; 49 | MobMat.col(1).setConstant(1.0); 50 | 51 | VectorXcd GFunc(X.size()); 52 | for (int i=0;i()<& A, const VectorXcd& b) 66 | { 67 | //creating real matrices 68 | SparseMatrix rA(A.rows()*2, A.cols()*2); 69 | 70 | vector > RealTris(A.nonZeros()*4); 71 | 72 | int Counter=0; 73 | for (int k=0; k::InnerIterator it(A,k); it; ++it){ 75 | RealTris[Counter++]=Triplet(it.row(), it.col(), it.value().real()); 76 | RealTris[Counter++]=Triplet(it.row(), it.col()+A.cols(), -it.value().imag()); 77 | RealTris[Counter++]=Triplet(it.row()+A.rows(), it.col(), it.value().imag()); 78 | RealTris[Counter++]=Triplet(it.row()+A.rows(), it.col()+A.cols(), it.value().real()); 79 | } 80 | } 81 | rA.setFromTriplets(RealTris.begin(), RealTris.end()); 82 | VectorXd rb(b.rows()*2); 83 | 84 | rb< > >(rA, rb, false); 87 | 88 | int ComplexSize=A.cols(); 89 | 90 | VectorXcd Solution(ComplexSize); 91 | for (int i=0;i 13 | #include 14 | #include 15 | 16 | using namespace Eigen; 17 | using namespace std; 18 | 19 | typedef std::complex Complex; 20 | 21 | Vector2cd GetSingleMobius(const VectorXcd& OrigVc, const VectorXcd& X); 22 | 23 | VectorXcd SolveComplexSytem(const SparseMatrix& A, const VectorXcd& b); 24 | 25 | void GetComplexMobiusCoeffs(Complex& a, Complex& b, Complex& c, Complex& d, const Vector3cd& z, const Vector3cd& w); 26 | 27 | RowVector4d Rot2Quat(Matrix3d& R); 28 | 29 | 30 | MatrixXd GetCenters(const MatrixXd& V, const MatrixXi& D, const MatrixXi& F); 31 | 32 | 33 | 34 | 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /FileDialog.h: -------------------------------------------------------------------------------- 1 | // 2 | // Filedialog.h 3 | // testigl 4 | // 5 | // Created by Amir Vaxman on 12/08/14. 6 | // Copyright (c) 2014 Amir Vaxman. All rights reserved. 7 | // 8 | 9 | #ifndef testigl_Filedialog_h 10 | #define testigl_Filedialog_h 11 | 12 | #include 13 | #define FILE_DIALOG_MAX_BUFFER 1024 14 | 15 | // Sets buffer to a path to an existing file 16 | // buffer[0]=0 on cancel 17 | // 18 | // Usage: 19 | // char buffer[FILE_DIALOG_MAX_BUFFER]; 20 | // get_open_file_path(buffer); 21 | void get_open_file_path(char buffer[]){ 22 | #ifdef __APPLE__ 23 | // For apple use applescript hack 24 | FILE * output = popen( 25 | "osascript -e \"" 26 | " tell application \\\"System Events\\\"\n" 27 | " activate\n" 28 | " set existing_file to choose file\n" 29 | " end tell\n" 30 | " set existing_file_path to (POSIX path of (existing_file))\n" 31 | "\" 2>/dev/null | tr -d '\n' ","r"); 32 | while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL ){ 33 | } 34 | #else 35 | // For every other machine type 36 | printf("Please enter a file path: "); 37 | gets(buffer); 38 | #endif 39 | } 40 | 41 | // Sets buffer to a path to a new/existing file 42 | // buffer[0]=0 on cancel 43 | // 44 | // Usage: 45 | // char buffer[FILE_DIALOG_MAX_BUFFER]; 46 | // get_save_file_path(buffer); 47 | void get_save_file_path(char buffer[]){ 48 | #ifdef __APPLE__ 49 | // For apple use applescript hack 50 | // There is currently a bug in Applescript that strips extensions off 51 | // of chosen existing files in the "choose file name" dialog 52 | // I'm assuming that will be fixed soon :-) 53 | FILE * output = popen( 54 | "osascript -e \"" 55 | " tell application \\\"System Events\\\"\n" 56 | " activate\n" 57 | " set existing_file to choose file name\n" 58 | " end tell\n" 59 | " set existing_file_path to (POSIX path of (existing_file))\n" 60 | "\" 2>/dev/null | tr -d '\n' ","r"); 61 | while ( fgets(buffer, FILE_DIALOG_MAX_BUFFER, output) != NULL ){ 62 | } 63 | #else 64 | // For every other machine type 65 | printf("Please enter a file path: "); 66 | gets(buffer); 67 | #endif 68 | } 69 | 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /InterpolateTraits.h: -------------------------------------------------------------------------------- 1 | // 2 | // InterpolateTraits.h 3 | // testigl 4 | // 5 | // Created by Amir Vaxman on 30/09/14. 6 | // Copyright (c) 2014 Amir Vaxman. All rights reserved. 7 | // 8 | 9 | #ifndef MoebiusCode_InterpolateTraits_h 10 | #define MoebiusCode_InterpolateTraits_h 11 | 12 | #include "AuxSparse.h" 13 | #include "MobiusFromShapes.h" 14 | #include "InitialSolution3DTraits.h" 15 | #include "QuadConstSolver.h" 16 | #include "QuaternionOps.h" 17 | #include "ExtraFunctions.h" 18 | 19 | //currently not treating the const indices at all 20 | 21 | class InterpolateTraits2D{ 22 | public: 23 | double OffWeight; 24 | double PosWeight; 25 | MatrixXi E2V, E2F, E2Fi, F; 26 | VectorXi InnerEdges, ConstIndices; 27 | 28 | SparseMatrix d0; 29 | SparseMatrix IDMat; 30 | 31 | VectorXcd SourceVc; 32 | 33 | SparseMatrix gGlobal; 34 | 35 | 36 | //VectorXd OrigLengths, DeformLengths, PrescribeLengths; 37 | VectorXcd InitSolution; 38 | VectorXcd InterpEdgeDeviations; 39 | VectorXcd ConstPoses; 40 | Vector2cd Interpcd; 41 | 42 | double SmoothFactor; 43 | double CloseFactor; 44 | double ConstTolerance; 45 | double VertexTolerance; 46 | 47 | 48 | void Initialize(const VectorXcd& inSourceVc, const VectorXcd& inTargetVc, const VectorXcd& inInterpEdgeDeviations, const Vector2cd& inInterpcd, const MatrixXi& inF, const MatrixXi& inE2V, const VectorXi& inInnerEdges, const MatrixXi& inE2F, const MatrixXi& inE2Fi, const VectorXi& inConstIndices, const VectorXcd& inConstPoses, const SparseMatrix ind0, double t, const VectorXcd& inInitSolution){ 49 | 50 | F=inF; E2V=inE2V; E2F=inE2F; InnerEdges=inInnerEdges; E2F=inE2F; E2Fi=inE2Fi; ConstIndices=inConstIndices; 51 | InitSolution=inInitSolution; 52 | d0=ind0; 53 | SourceVc=inSourceVc; 54 | ConstPoses=inConstPoses; 55 | Interpcd=inInterpcd; 56 | InterpEdgeDeviations=inInterpEdgeDeviations; 57 | 58 | //InitialSolution2DTraits ist; 59 | //ist.Initialize(ConstIndices, SourceVc, TargetConstPoses, TargetConstX); 60 | //cout<<"Finding Base Mobius Transformation:"< qcs(ist); 62 | //TargetConstX=qcs.Solve(TargetConstX, 1.0, 25); 63 | 64 | //for (int i=0;i > ConstPairs; 72 | for (int i=0;i(i,j));*/ 75 | 76 | 77 | //computing current deform error 78 | 79 | 80 | /*VectorXcd InterpConstDeviations(ConstPairs.size()); 81 | MatrixXcd dConst(ConstPairs.size(), ConstIndices.size()); 82 | dConst.setZero(); 83 | VectorXcd MobEdgeVectors(ConstPairs.size()); 84 | for (int i=0;i EvalGradient(const VectorXcd& CurrSolution){ 164 | 165 | //VectorXcd CurrSolution(CurrSolutionReal.size()/2); 166 | //CurrSolution.array().real()=CurrSolutionReal.head(CurrSolutionReal.size()/2); 167 | //CurrSolution.array().imag()=CurrSolutionReal.tail(CurrSolutionReal.size()/2); 168 | 169 | VectorXcd CurrMobRecips=CurrSolution.head(SourceVc.rows()); 170 | VectorXcd CurrLocations=CurrSolution.segment(SourceVc.rows(),SourceVc.rows()); 171 | 172 | SparseMatrix gCurrEdges=-SparseDiagonalMatrix(InterpEdgeDeviations)*d0; 173 | SparseMatrix gCurrMobiusEdges(E2V.rows(), SourceVc.rows()); 174 | vector > gCurrMobiusEdgesTris; 175 | for (int i=0;i(i,E2V(i,1),CurrMobRecips(E2V(i,0))*(SourceVc(E2V(i,1))-SourceVc(E2V(i,0))))); 177 | gCurrMobiusEdgesTris.push_back(Triplet(i,E2V(i,0),CurrMobRecips(E2V(i,1))*(SourceVc(E2V(i,1))-SourceVc(E2V(i,0))))); 178 | } 179 | 180 | gCurrMobiusEdges.setFromTriplets(gCurrMobiusEdgesTris.begin(), gCurrMobiusEdgesTris.end()); 181 | 182 | SparseMatrix gAMAPEnergy=SparseBlock(gCurrMobiusEdges, gCurrEdges,true); 183 | 184 | SparseMatrix gPos(ConstIndices.size(), CurrSolution.size()); 185 | vector > gPosTris; 186 | for (int i=0;i(i,SourceVc.rows()+ConstIndices(i),1.0)); 188 | 189 | gPos.setFromTriplets(gPosTris.begin(), gPosTris.end()); 190 | 191 | SparseMatrix ComplexGradient=SparseBlock(SparseBlock(CloseFactor*IDMat,SmoothFactor*gAMAPEnergy, false),gPos,false);//, gPos, false); 192 | 193 | return ComplexGradient; 194 | } 195 | 196 | void Reformulate(int CurrIter, int MaxIterations, const VectorXcd& CurrSolution) 197 | { 198 | InitSolution=CurrSolution; 199 | SmoothFactor*=0.95; 200 | 201 | } 202 | 203 | double GetConstError(const VectorXcd& CurrSolution) 204 | { 205 | 206 | VectorXcd CurrMobRecips=CurrSolution.head(SourceVc.rows()); 207 | VectorXcd CurrLocations=CurrSolution.segment(SourceVc.rows(),SourceVc.rows()); 208 | 209 | VectorXcd CurrEdges=(d0*CurrLocations).cwiseProduct(InterpEdgeDeviations); 210 | VectorXcd CurrMobiusEdges(E2V.rows()); 211 | for (int i=0;i(); 227 | return EnergyVec.lpNorm(); 228 | } 229 | 230 | bool isTerminate(const VectorXcd& CurrSolution){ 231 | //VectorXcd CurrSolution(CurrSolutionReal.size()/2); 232 | //CurrSolution.array().real()=CurrSolutionReal.head(CurrSolutionReal.size()/2); 233 | //CurrSolution.array().imag()=CurrSolutionReal.tail(CurrSolutionReal.size()/2); 234 | 235 | VectorXcd CurrLocations=CurrSolution.segment(SourceVc.rows(),SourceVc.rows()); 236 | VectorXcd InitLocations=InitSolution.segment(SourceVc.rows(),SourceVc.rows()); 237 | bool NoVerticesMoved=((CurrLocations-InitLocations).lpNorm()()< d0; 262 | SparseMatrix IDMat; 263 | 264 | double SmoothFactor; 265 | double CloseFactor; 266 | double ConstTolerance; 267 | 268 | 269 | void Initialize(const MatrixXd& inSourceVq, const MatrixXd& TargetVq, const MatrixXd& TargetX, const MatrixXd& TargetEdgeDeviations, const MatrixXi& inF, const MatrixXi& inE2V, const VectorXi& inInnerEdges, const MatrixXi& inE2F, const MatrixXi& inE2Fi, const VectorXi& inConstIndices, const MatrixXd& inConstPoses, const SparseMatrix& ind0, const double t, const VectorXd& inInitSolution){ 270 | 271 | 272 | F=inF; E2V=inE2V; E2F=inE2F; InnerEdges=inInnerEdges; E2F=inE2F; E2Fi=inE2Fi; ConstIndices=inConstIndices; 273 | InitSolution=inInitSolution; 274 | SourceVq=inSourceVq; 275 | 276 | ConstPoses=inConstPoses; 277 | 278 | d0=ind0; 279 | 280 | MatrixXd SourceConstPoses(ConstIndices.size(),4); 281 | MatrixXd TargetConstPoses(ConstIndices.size(),4); 282 | InterpConstPoses.resize(3*ConstIndices.size()); 283 | 284 | MatrixXd InterpConstX(ConstIndices.size(),4); 285 | VectorXd TargetConstX(4*ConstIndices.size()); 286 | 287 | for (int i=0;i qcs(ist); 296 | TargetConstX=qcs.Solve(TargetConstX, 1.0, 25); 297 | 298 | for (int i=0;i > ConstPairs; 306 | for (int i=0;i(i,j)); 309 | 310 | 311 | //computing current deform error 312 | MatrixXd InterpConstDeviations(ConstPairs.size(),4); 313 | MatrixXd dConst(ConstPairs.size(), ConstIndices.size()); 314 | 315 | dConst.setZero(); 316 | 317 | MatrixXd MobEdgeVectors(ConstPairs.size(),4); 318 | 319 | for (int i=0;i FEGradient(CurrConst.size(), CurrSolution.size()); 370 | vector > FEGradientTris; 371 | for (int i=0;i10e-7) 377 | FEGradientTris.push_back(Triplet(j,i,CurrGradient(j))); 378 | } 379 | 380 | FEGradient.setFromTriplets(FEGradientTris.begin(), FEGradientTris.end()); 381 | SparseMatrix OrigGradient=EvalGradient(CurrSolution); 382 | SparseMatrix DiffMat=FEGradient-OrigGradient; 383 | double maxcoeff=-32767.0; 384 | int Maxi,Maxj; 385 | for (int k=0; k::InnerIterator it(DiffMat,k); it; ++it){ 387 | if (maxcoeff10e-6){ 394 | cout<<"Gradient Discrepancy at: ("< EvalGradient(const VectorXd& CurrSolution){ 446 | 447 | VectorXd CurrX=CurrSolution.head(4*SourceVq.rows()); 448 | VectorXd CurrLocations=CurrSolution.segment(4*SourceVq.rows(),3*SourceVq.rows()); 449 | VectorXd ExtEdgeVectors(4*E2V.rows()); ExtEdgeVectors.setZero(); 450 | VectorXd CurrWij=d0*CurrLocations; 451 | for (int i=0;i > gMobEdgesTris, gCurrEdgesTris; 457 | for (int i=0;i(4*i,MatPosj, ResttoRight(0))); 478 | gMobEdgesTris.push_back(Triplet(4*i,MatPosj+1,ResttoRight(1))); 479 | gMobEdgesTris.push_back(Triplet(4*i,MatPosj+2,ResttoRight(2))); 480 | gMobEdgesTris.push_back(Triplet(4*i,MatPosj+3,ResttoRight(3))); 481 | 482 | gMobEdgesTris.push_back(Triplet(4*i+1,MatPosj, ResttoRight(1))); 483 | gMobEdgesTris.push_back(Triplet(4*i+1,MatPosj+1,-ResttoRight(0))); 484 | gMobEdgesTris.push_back(Triplet(4*i+1,MatPosj+2,-ResttoRight(3))); 485 | gMobEdgesTris.push_back(Triplet(4*i+1,MatPosj+3, ResttoRight(2))); 486 | 487 | gMobEdgesTris.push_back(Triplet(4*i+2,MatPosj, ResttoRight(2))); 488 | gMobEdgesTris.push_back(Triplet(4*i+2,MatPosj+1, ResttoRight(3))); 489 | gMobEdgesTris.push_back(Triplet(4*i+2,MatPosj+2,-ResttoRight(0))); 490 | gMobEdgesTris.push_back(Triplet(4*i+2,MatPosj+3,-ResttoRight(1))); 491 | 492 | gMobEdgesTris.push_back(Triplet(4*i+3,MatPosj, ResttoRight(3))); 493 | gMobEdgesTris.push_back(Triplet(4*i+3,MatPosj+1,-ResttoRight(2))); 494 | gMobEdgesTris.push_back(Triplet(4*i+3,MatPosj+2, ResttoRight(1))); 495 | gMobEdgesTris.push_back(Triplet(4*i+3,MatPosj+3,-ResttoRight(0))); 496 | 497 | //Derivative by Gi, using rest to left as "e": 498 | //[ re, -vex, -vey, -vez] 499 | //[ vex, re, -vez, vey] 500 | //[ vey, vez, re, -vex] 501 | //[ vez, -vey, vex, re] 502 | 503 | gMobEdgesTris.push_back(Triplet(4*i,MatPosi, ResttoLeft(0))); 504 | gMobEdgesTris.push_back(Triplet(4*i,MatPosi+1,-ResttoLeft(1))); 505 | gMobEdgesTris.push_back(Triplet(4*i,MatPosi+2,-ResttoLeft(2))); 506 | gMobEdgesTris.push_back(Triplet(4*i,MatPosi+3,-ResttoLeft(3))); 507 | 508 | gMobEdgesTris.push_back(Triplet(4*i+1,MatPosi, ResttoLeft(1))); 509 | gMobEdgesTris.push_back(Triplet(4*i+1,MatPosi+1, ResttoLeft(0))); 510 | gMobEdgesTris.push_back(Triplet(4*i+1,MatPosi+2,-ResttoLeft(3))); 511 | gMobEdgesTris.push_back(Triplet(4*i+1,MatPosi+3, ResttoLeft(2))); 512 | 513 | gMobEdgesTris.push_back(Triplet(4*i+2,MatPosi, ResttoLeft(2))); 514 | gMobEdgesTris.push_back(Triplet(4*i+2,MatPosi+1, ResttoLeft(3))); 515 | gMobEdgesTris.push_back(Triplet(4*i+2,MatPosi+2, ResttoLeft(0))); 516 | gMobEdgesTris.push_back(Triplet(4*i+2,MatPosi+3,-ResttoLeft(1))); 517 | 518 | gMobEdgesTris.push_back(Triplet(4*i+3,MatPosi, ResttoLeft(3))); 519 | gMobEdgesTris.push_back(Triplet(4*i+3,MatPosi+1,-ResttoLeft(2))); 520 | gMobEdgesTris.push_back(Triplet(4*i+3,MatPosi+2, ResttoLeft(1))); 521 | gMobEdgesTris.push_back(Triplet(4*i+3,MatPosi+3, ResttoLeft(0))); 522 | 523 | //Derivative with relation to positions 524 | //Derivative by Wij (with proper sign), using rest to left (Cij) as "e": 525 | //[ re, -vex, -vey, -vez] 526 | //[ vex, re, -vez, vey] 527 | //[ vey, vez, re, -vex] 528 | //[ vez, -vey, vex, re] 529 | //gCurrEdgesTris.push_back(Triplet(4*i,CurrX.size()+4*E2V(i,1), Cij(0))); 530 | gCurrEdgesTris.push_back(Triplet(4*i,CurrX.size()+3*E2V(i,1), -Cij(1))); 531 | gCurrEdgesTris.push_back(Triplet(4*i,CurrX.size()+3*E2V(i,1)+1,-Cij(2))); 532 | gCurrEdgesTris.push_back(Triplet(4*i,CurrX.size()+3*E2V(i,1)+2,-Cij(3))); 533 | 534 | //gCurrEdgesTris.push_back(Triplet(4*i+1,CurrX.size()+4*E2V(i,1), Cij(1))); 535 | gCurrEdgesTris.push_back(Triplet(4*i+1,CurrX.size()+3*E2V(i,1), Cij(0))); 536 | gCurrEdgesTris.push_back(Triplet(4*i+1,CurrX.size()+3*E2V(i,1)+1,-Cij(3))); 537 | gCurrEdgesTris.push_back(Triplet(4*i+1,CurrX.size()+3*E2V(i,1)+2, Cij(2))); 538 | 539 | //gCurrEdgesTris.push_back(Triplet(4*i+2,CurrX.size()+4*E2V(i,1), Cij(2))); 540 | gCurrEdgesTris.push_back(Triplet(4*i+2,CurrX.size()+3*E2V(i,1), Cij(3))); 541 | gCurrEdgesTris.push_back(Triplet(4*i+2,CurrX.size()+3*E2V(i,1)+1, Cij(0))); 542 | gCurrEdgesTris.push_back(Triplet(4*i+2,CurrX.size()+3*E2V(i,1)+2,-Cij(1))); 543 | 544 | //gCurrEdgesTris.push_back(Triplet(4*i+3,CurrX.size()+4*E2V(i,1), Cij(3))); 545 | gCurrEdgesTris.push_back(Triplet(4*i+3,CurrX.size()+3*E2V(i,1),-Cij(2))); 546 | gCurrEdgesTris.push_back(Triplet(4*i+3,CurrX.size()+3*E2V(i,1)+1, Cij(1))); 547 | gCurrEdgesTris.push_back(Triplet(4*i+3,CurrX.size()+3*E2V(i,1)+2,Cij(0))); 548 | 549 | 550 | //gCurrEdgesTris.push_back(Triplet(4*i,CurrX.size()+4*E2V(i,0), -Cij(0))); 551 | gCurrEdgesTris.push_back(Triplet(4*i,CurrX.size()+3*E2V(i,0),Cij(1))); 552 | gCurrEdgesTris.push_back(Triplet(4*i,CurrX.size()+3*E2V(i,0)+1,Cij(2))); 553 | gCurrEdgesTris.push_back(Triplet(4*i,CurrX.size()+3*E2V(i,0)+2,Cij(3))); 554 | 555 | //gCurrEdgesTris.push_back(Triplet(4*i+1,CurrX.size()+4*E2V(i,0), -Cij(1))); 556 | gCurrEdgesTris.push_back(Triplet(4*i+1,CurrX.size()+3*E2V(i,0), -Cij(0))); 557 | gCurrEdgesTris.push_back(Triplet(4*i+1,CurrX.size()+3*E2V(i,0)+1,Cij(3))); 558 | gCurrEdgesTris.push_back(Triplet(4*i+1,CurrX.size()+3*E2V(i,0)+2, -Cij(2))); 559 | 560 | //gCurrEdgesTris.push_back(Triplet(4*i+2,CurrX.size()+4*E2V(i,0), -Cij(2))); 561 | gCurrEdgesTris.push_back(Triplet(4*i+2,CurrX.size()+3*E2V(i,0), -Cij(3))); 562 | gCurrEdgesTris.push_back(Triplet(4*i+2,CurrX.size()+3*E2V(i,0)+1, -Cij(0))); 563 | gCurrEdgesTris.push_back(Triplet(4*i+2,CurrX.size()+3*E2V(i,0)+2,Cij(1))); 564 | 565 | //gCurrEdgesTris.push_back(Triplet(4*i+3,CurrX.size()+4*E2V(i,0), -Cij(3))); 566 | gCurrEdgesTris.push_back(Triplet(4*i+3,CurrX.size()+3*E2V(i,0),Cij(2))); 567 | gCurrEdgesTris.push_back(Triplet(4*i+3,CurrX.size()+3*E2V(i,0)+1, -Cij(1))); 568 | gCurrEdgesTris.push_back(Triplet(4*i+3,CurrX.size()+3*E2V(i,0)+2,-Cij(0))); 569 | } 570 | 571 | SparseMatrix gMobEdges(4*E2V.rows(),CurrSolution.size()); 572 | gMobEdges.setFromTriplets(gMobEdgesTris.begin(), gMobEdgesTris.end()); 573 | 574 | SparseMatrix gCurrEdges(4*E2V.rows(), CurrSolution.size()); 575 | gCurrEdges.setFromTriplets(gCurrEdgesTris.begin(),gCurrEdgesTris.end()); 576 | SparseMatrix gAMAPEnergy=gMobEdges-gCurrEdges; 577 | 578 | SparseMatrix gPos(3*ConstIndices.size(), CurrSolution.size()); 579 | vector > gPosTris; 580 | for (int i=0;i(3*i+j, 4*SourceVq.rows()+3*ConstIndices(i)+j,1.0)); 583 | 584 | gPos.setFromTriplets(gPosTris.begin(), gPosTris.end()); 585 | 586 | SparseMatrix BasicGradient=SparseBlock(SparseBlock(CloseFactor*IDMat, SmoothFactor*gAMAPEnergy,false),gPos,false); 587 | 588 | 589 | return BasicGradient; 590 | 591 | } 592 | 593 | void Reformulate(int CurrIter, int MaxIterations, const VectorXd& CurrSolution) 594 | { 595 | InitSolution=CurrSolution; 596 | SmoothFactor*=0.5; 597 | } 598 | 599 | double GetConstError(const VectorXd& CurrSolution) 600 | { 601 | VectorXd CurrLocations=CurrSolution.segment(4*SourceVq.rows(),3*SourceVq.rows()); 602 | VectorXd PosVec(3*ConstIndices.size()); 603 | for (int i=0;i(); 607 | 608 | } 609 | 610 | bool isTerminate(const VectorXd& CurrSolution){ 611 | //VectorXcd CurrSolution(CurrSolutionReal.size()/2); 612 | //CurrSolution.array().real()=CurrSolutionReal.head(CurrSolutionReal.size()/2); 613 | //CurrSolution.array().imag()=CurrSolutionReal.tail(CurrSolutionReal.size()/2); 614 | 615 | VectorXd CurrLocations=CurrSolution.segment(4*SourceVq.rows(),3*SourceVq.rows()); 616 | VectorXd InitLocations=InitSolution.segment(4*SourceVq.rows(),3*SourceVq.rows()); 617 | bool NoVerticesMoved=((CurrLocations-InitLocations).lpNorm() d0Var; 633 | VectorXd d0Rhs; 634 | vector > AdjFaces; 635 | vector > AdjFacesi; 636 | 637 | MatrixXd OrigVq, DeformVq; 638 | 639 | VectorXd InitSolution; 640 | 641 | VectorXd AbsOrigCR, AbsDeformCR, AbsInterpCR; 642 | VectorXd RealOrigCR, RealDeformCR, RealInterpCR; 643 | 644 | VectorXi VarLocIndices; 645 | 646 | SparseMatrix IDMat; 647 | SparseMatrix NormSumMatrix; 648 | SparseMatrix CornerDiffLCRSmall, CornerDiffSmall, CornerDiffMat; 649 | 650 | double CloseFactor; 651 | double SmoothFactor; 652 | 653 | 654 | vector > CornerPairs; 655 | 656 | void Initialize(const MatrixXd& inOrigVq, const MatrixXd& inDeformVq, const MatrixXi& inF, MatrixXi& inF2E, MatrixXd& inF2ESigns, const MatrixXi& inE2V, const VectorXi& inInnerEdges, const MatrixXi& inE2F, const MatrixXi& inE2Fi, vector >& inAdjFaces, vector >& inAdjFacesi, const VectorXi& inConstIndices, VectorXi& inVarIndices, SparseMatrix& ind0var, VectorXd& ind0Rhs, VectorXd inAbsOrigCR, VectorXd& inAbsDeformCR, VectorXd& inRealOrigCR, VectorXd& inRealDeformCR, vector >& inCornerPairs,const double t, const VectorXd& inInitSolution){ 657 | F=inF; E2V=inE2V; F2E=inF2E; F2ESigns=inF2ESigns; E2F=inE2F; InnerEdges=inInnerEdges; E2F=inE2F; E2Fi=inE2Fi; ConstIndices=inConstIndices; 658 | 659 | 660 | OrigVq=inOrigVq; 661 | DeformVq=inDeformVq; 662 | InitSolution=inInitSolution; 663 | AbsInterpCR.resize(InnerEdges.size()); 664 | RealInterpCR.resize(InnerEdges.size()); 665 | AbsOrigCR=inAbsOrigCR; 666 | AbsDeformCR=inAbsDeformCR; 667 | RealOrigCR=inRealOrigCR; 668 | RealDeformCR=inRealDeformCR; 669 | 670 | VarIndices=inVarIndices; 671 | d0Var=ind0var; d0Rhs=ind0Rhs; 672 | CornerPairs=inCornerPairs; 673 | AdjFaces=inAdjFaces; 674 | AdjFacesi=inAdjFacesi; 675 | 676 | for (int i=0;i > CornerDiffLCRTris, CornerDiffTris; 684 | //creating smoothness matrix for G values 685 | for (int i=0;i(2*i, CornerPairs[i].first,1.0)); 687 | CornerDiffLCRTris.push_back(Triplet(2*i+1, CornerPairs[i].second,-AbsInterpCR(i))); 688 | 689 | CornerDiffTris.push_back(Triplet(2*i, CornerPairs[i].first,1.0)); 690 | CornerDiffTris.push_back(Triplet(2*i+1, CornerPairs[i].second,-1.0)); 691 | } 692 | 693 | CornerDiffLCRSmall.resize(2*InnerEdges.size(), 3*F.rows()); 694 | CornerDiffLCRSmall.setFromTriplets(CornerDiffLCRTris.begin(), CornerDiffLCRTris.end()); 695 | 696 | CornerDiffSmall.resize(2*InnerEdges.size(), 3*F.rows()); 697 | CornerDiffSmall.setFromTriplets(CornerDiffTris.begin(), CornerDiffTris.end()); 698 | 699 | SparseMatrix eye4; 700 | igl::speye(4, eye4); 701 | SparseMatrix CornerDiffOnlyG=Eigen::kroneckerProduct(CornerDiffSmall,eye4); 702 | SparseMatrix ZeroMat(CornerDiffOnlyG.rows(), 3*VarIndices.size()); 703 | CornerDiffMat=SparseBlock(CornerDiffOnlyG, ZeroMat, true); 704 | 705 | 706 | VarLocIndices.resize(12*F.rows()+3*VarIndices.size()); 707 | for (int i=0;i<12*F.rows();i++) 708 | VarLocIndices(i)=i; 709 | for (int i=0;i > NormSumTris; 717 | for (int i=0;i<3*F.rows();i++) 718 | for(int j=0;j<4;j++) 719 | NormSumTris.push_back(Triplet(i,4*i+j,1.0)); 720 | 721 | NormSumMatrix.resize(3*F.rows(),12*F.rows()+3*VarIndices.size()); 722 | NormSumMatrix.setFromTriplets(NormSumTris.begin(), NormSumTris.end()); 723 | 724 | CloseFactor=10e-6; 725 | SmoothFactor=100; 726 | 727 | } 728 | 729 | VectorXd EvalEnergy(const VectorXd& CurrSolution){ 730 | 731 | VectorXd CurrGInv=CurrSolution.head(12*F.rows()); 732 | VectorXd CurrLocations=CurrSolution.tail(3*VarIndices.size()); 733 | 734 | VectorXd CompVec(12*F.rows()); 735 | VectorXd EdgeVectors=d0Var*CurrLocations-d0Rhs; 736 | for (int i=0;i EvalGradient(const VectorXd& CurrSolution){ 775 | 776 | VectorXd CurrGInv=CurrSolution.head(12*F.rows()); 777 | VectorXd CurrLocations=CurrSolution.tail(3*VarIndices.size()); 778 | 779 | vector > gCompTris; 780 | for (int i=0;i(CurrRow,MatPosj, ResttoRight(0))); 802 | gCompTris.push_back(Triplet(CurrRow,MatPosj+1,ResttoRight(1))); 803 | gCompTris.push_back(Triplet(CurrRow,MatPosj+2,ResttoRight(2))); 804 | gCompTris.push_back(Triplet(CurrRow,MatPosj+3,ResttoRight(3))); 805 | 806 | gCompTris.push_back(Triplet(CurrRow+1,MatPosj, ResttoRight(1))); 807 | gCompTris.push_back(Triplet(CurrRow+1,MatPosj+1,-ResttoRight(0))); 808 | gCompTris.push_back(Triplet(CurrRow+1,MatPosj+2,-ResttoRight(3))); 809 | gCompTris.push_back(Triplet(CurrRow+1,MatPosj+3, ResttoRight(2))); 810 | 811 | gCompTris.push_back(Triplet(CurrRow+2,MatPosj, ResttoRight(2))); 812 | gCompTris.push_back(Triplet(CurrRow+2,MatPosj+1, ResttoRight(3))); 813 | gCompTris.push_back(Triplet(CurrRow+2,MatPosj+2,-ResttoRight(0))); 814 | gCompTris.push_back(Triplet(CurrRow+2,MatPosj+3,-ResttoRight(1))); 815 | 816 | gCompTris.push_back(Triplet(CurrRow+3,MatPosj, ResttoRight(3))); 817 | gCompTris.push_back(Triplet(CurrRow+3,MatPosj+1,-ResttoRight(2))); 818 | gCompTris.push_back(Triplet(CurrRow+3,MatPosj+2, ResttoRight(1))); 819 | gCompTris.push_back(Triplet(CurrRow+3,MatPosj+3,-ResttoRight(0))); 820 | 821 | //Derivative by Gi, using rest to left as "e": 822 | //[ re, -vex, -vey, -vez] 823 | //[ vex, re, -vez, vey] 824 | //[ vey, vez, re, -vex] 825 | //[ vez, -vey, vex, re] 826 | 827 | gCompTris.push_back(Triplet(CurrRow,MatPosi, ResttoLeft(0))); 828 | gCompTris.push_back(Triplet(CurrRow,MatPosi+1,-ResttoLeft(1))); 829 | gCompTris.push_back(Triplet(CurrRow,MatPosi+2,-ResttoLeft(2))); 830 | gCompTris.push_back(Triplet(CurrRow,MatPosi+3,-ResttoLeft(3))); 831 | 832 | gCompTris.push_back(Triplet(CurrRow+1,MatPosi, ResttoLeft(1))); 833 | gCompTris.push_back(Triplet(CurrRow+1,MatPosi+1, ResttoLeft(0))); 834 | gCompTris.push_back(Triplet(CurrRow+1,MatPosi+2,-ResttoLeft(3))); 835 | gCompTris.push_back(Triplet(CurrRow+1,MatPosi+3, ResttoLeft(2))); 836 | 837 | gCompTris.push_back(Triplet(CurrRow+2,MatPosi, ResttoLeft(2))); 838 | gCompTris.push_back(Triplet(CurrRow+2,MatPosi+1, ResttoLeft(3))); 839 | gCompTris.push_back(Triplet(CurrRow+2,MatPosi+2, ResttoLeft(0))); 840 | gCompTris.push_back(Triplet(CurrRow+2,MatPosi+3,-ResttoLeft(1))); 841 | 842 | gCompTris.push_back(Triplet(CurrRow+3,MatPosi, ResttoLeft(3))); 843 | gCompTris.push_back(Triplet(CurrRow+3,MatPosi+1,-ResttoLeft(2))); 844 | gCompTris.push_back(Triplet(CurrRow+3,MatPosi+2, ResttoLeft(1))); 845 | gCompTris.push_back(Triplet(CurrRow+3,MatPosi+3, ResttoLeft(0))); 846 | 847 | //Derivative with relation to positions 848 | gCompTris.push_back(Triplet(CurrRow+1,CurrGInv.size()+3*F(i,(j+1)%3), -1.0)); 849 | gCompTris.push_back(Triplet(CurrRow+2,CurrGInv.size()+3*F(i,(j+1)%3)+1,-1.0)); 850 | gCompTris.push_back(Triplet(CurrRow+3,CurrGInv.size()+3*F(i,(j+1)%3)+2,-1.0)); 851 | 852 | gCompTris.push_back(Triplet(CurrRow+1,CurrGInv.size()+3*F(i,j), 1.0)); 853 | gCompTris.push_back(Triplet(CurrRow+2,CurrGInv.size()+3*F(i,j)+1,1.0)); 854 | gCompTris.push_back(Triplet(CurrRow+3,CurrGInv.size()+3*F(i,j)+2,1.0)); 855 | 856 | } 857 | } 858 | 859 | SparseMatrix gCompFull(12*F.rows(), 3*OrigVq.rows()+CurrGInv.size()); 860 | SparseMatrix gComp(12*F.rows(), 3*VarIndices.size()+CurrGInv.size()); 861 | gCompFull.setFromTriplets(gCompTris.begin(),gCompTris.end()); 862 | 863 | igl::slice(gCompFull,VarLocIndices, 2,gComp); 864 | 865 | SparseMatrix gLCR=CornerDiffLCRSmall*NormSumMatrix*SparseDiagonalMatrix(2*CurrSolution); 866 | 867 | SparseMatrix Gradient=SparseBlock(SparseBlock(CloseFactor*IDMat, SmoothFactor*CornerDiffMat, false), SparseBlock(gComp,gLCR, false),false); 868 | 869 | return Gradient; 870 | 871 | } 872 | 873 | 874 | void Reformulate(int CurrIter, int MaxIterations, VectorXd CurrSolution){ 875 | } 876 | 877 | double GetConstError(VectorXd CurrError) 878 | { 879 | return CurrError.lpNorm(); 880 | } 881 | 882 | };*/ 883 | 884 | 885 | #endif 886 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License, version 2.0 2 | 3 | 1. Definitions 4 | 5 | 1.1. "Contributor" 6 | 7 | means each individual or legal entity that creates, contributes to the 8 | creation of, or owns Covered Software. 9 | 10 | 1.2. "Contributor Version" 11 | 12 | means the combination of the Contributions of others (if any) used by a 13 | Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | 17 | means Covered Software of a particular Contributor. 18 | 19 | 1.4. "Covered Software" 20 | 21 | means Source Code Form to which the initial Contributor has attached the 22 | notice in Exhibit A, the Executable Form of such Source Code Form, and 23 | Modifications of such Source Code Form, in each case including portions 24 | thereof. 25 | 26 | 1.5. "Incompatible With Secondary Licenses" 27 | means 28 | 29 | a. that the initial Contributor has attached the notice described in 30 | Exhibit B to the Covered Software; or 31 | 32 | b. that the Covered Software was made available under the terms of 33 | version 1.1 or earlier of the License, but not also under the terms of 34 | a Secondary License. 35 | 36 | 1.6. "Executable Form" 37 | 38 | means any form of the work other than Source Code Form. 39 | 40 | 1.7. "Larger Work" 41 | 42 | means a work that combines Covered Software with other material, in a 43 | separate file or files, that is not Covered Software. 44 | 45 | 1.8. "License" 46 | 47 | means this document. 48 | 49 | 1.9. "Licensable" 50 | 51 | means having the right to grant, to the maximum extent possible, whether 52 | at the time of the initial grant or subsequently, any and all of the 53 | rights conveyed by this License. 54 | 55 | 1.10. "Modifications" 56 | 57 | means any of the following: 58 | 59 | a. any file in Source Code Form that results from an addition to, 60 | deletion from, or modification of the contents of Covered Software; or 61 | 62 | b. any new file in Source Code Form that contains any Covered Software. 63 | 64 | 1.11. "Patent Claims" of a Contributor 65 | 66 | means any patent claim(s), including without limitation, method, 67 | process, and apparatus claims, in any patent Licensable by such 68 | Contributor that would be infringed, but for the grant of the License, 69 | by the making, using, selling, offering for sale, having made, import, 70 | or transfer of either its Contributions or its Contributor Version. 71 | 72 | 1.12. "Secondary License" 73 | 74 | means either the GNU General Public License, Version 2.0, the GNU Lesser 75 | General Public License, Version 2.1, the GNU Affero General Public 76 | License, Version 3.0, or any later versions of those licenses. 77 | 78 | 1.13. "Source Code Form" 79 | 80 | means the form of the work preferred for making modifications. 81 | 82 | 1.14. "You" (or "Your") 83 | 84 | means an individual or a legal entity exercising rights under this 85 | License. For legal entities, "You" includes any entity that controls, is 86 | controlled by, or is under common control with You. For purposes of this 87 | definition, "control" means (a) the power, direct or indirect, to cause 88 | the direction or management of such entity, whether by contract or 89 | otherwise, or (b) ownership of more than fifty percent (50%) of the 90 | outstanding shares or beneficial ownership of such entity. 91 | 92 | 93 | 2. License Grants and Conditions 94 | 95 | 2.1. Grants 96 | 97 | Each Contributor hereby grants You a world-wide, royalty-free, 98 | non-exclusive license: 99 | 100 | a. under intellectual property rights (other than patent or trademark) 101 | Licensable by such Contributor to use, reproduce, make available, 102 | modify, display, perform, distribute, and otherwise exploit its 103 | Contributions, either on an unmodified basis, with Modifications, or 104 | as part of a Larger Work; and 105 | 106 | b. under Patent Claims of such Contributor to make, use, sell, offer for 107 | sale, have made, import, and otherwise transfer either its 108 | Contributions or its Contributor Version. 109 | 110 | 2.2. Effective Date 111 | 112 | The licenses granted in Section 2.1 with respect to any Contribution 113 | become effective for each Contribution on the date the Contributor first 114 | distributes such Contribution. 115 | 116 | 2.3. Limitations on Grant Scope 117 | 118 | The licenses granted in this Section 2 are the only rights granted under 119 | this License. No additional rights or licenses will be implied from the 120 | distribution or licensing of Covered Software under this License. 121 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 122 | Contributor: 123 | 124 | a. for any code that a Contributor has removed from Covered Software; or 125 | 126 | b. for infringements caused by: (i) Your and any other third party's 127 | modifications of Covered Software, or (ii) the combination of its 128 | Contributions with other software (except as part of its Contributor 129 | Version); or 130 | 131 | c. under Patent Claims infringed by Covered Software in the absence of 132 | its Contributions. 133 | 134 | This License does not grant any rights in the trademarks, service marks, 135 | or logos of any Contributor (except as may be necessary to comply with 136 | the notice requirements in Section 3.4). 137 | 138 | 2.4. Subsequent Licenses 139 | 140 | No Contributor makes additional grants as a result of Your choice to 141 | distribute the Covered Software under a subsequent version of this 142 | License (see Section 10.2) or under the terms of a Secondary License (if 143 | permitted under the terms of Section 3.3). 144 | 145 | 2.5. Representation 146 | 147 | Each Contributor represents that the Contributor believes its 148 | Contributions are its original creation(s) or it has sufficient rights to 149 | grant the rights to its Contributions conveyed by this License. 150 | 151 | 2.6. Fair Use 152 | 153 | This License is not intended to limit any rights You have under 154 | applicable copyright doctrines of fair use, fair dealing, or other 155 | equivalents. 156 | 157 | 2.7. Conditions 158 | 159 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in 160 | Section 2.1. 161 | 162 | 163 | 3. Responsibilities 164 | 165 | 3.1. Distribution of Source Form 166 | 167 | All distribution of Covered Software in Source Code Form, including any 168 | Modifications that You create or to which You contribute, must be under 169 | the terms of this License. You must inform recipients that the Source 170 | Code Form of the Covered Software is governed by the terms of this 171 | License, and how they can obtain a copy of this License. You may not 172 | attempt to alter or restrict the recipients' rights in the Source Code 173 | Form. 174 | 175 | 3.2. Distribution of Executable Form 176 | 177 | If You distribute Covered Software in Executable Form then: 178 | 179 | a. such Covered Software must also be made available in Source Code Form, 180 | as described in Section 3.1, and You must inform recipients of the 181 | Executable Form how they can obtain a copy of such Source Code Form by 182 | reasonable means in a timely manner, at a charge no more than the cost 183 | of distribution to the recipient; and 184 | 185 | b. You may distribute such Executable Form under the terms of this 186 | License, or sublicense it under different terms, provided that the 187 | license for the Executable Form does not attempt to limit or alter the 188 | recipients' rights in the Source Code Form under this License. 189 | 190 | 3.3. Distribution of a Larger Work 191 | 192 | You may create and distribute a Larger Work under terms of Your choice, 193 | provided that You also comply with the requirements of this License for 194 | the Covered Software. If the Larger Work is a combination of Covered 195 | Software with a work governed by one or more Secondary Licenses, and the 196 | Covered Software is not Incompatible With Secondary Licenses, this 197 | License permits You to additionally distribute such Covered Software 198 | under the terms of such Secondary License(s), so that the recipient of 199 | the Larger Work may, at their option, further distribute the Covered 200 | Software under the terms of either this License or such Secondary 201 | License(s). 202 | 203 | 3.4. Notices 204 | 205 | You may not remove or alter the substance of any license notices 206 | (including copyright notices, patent notices, disclaimers of warranty, or 207 | limitations of liability) contained within the Source Code Form of the 208 | Covered Software, except that You may alter any license notices to the 209 | extent required to remedy known factual inaccuracies. 210 | 211 | 3.5. Application of Additional Terms 212 | 213 | You may choose to offer, and to charge a fee for, warranty, support, 214 | indemnity or liability obligations to one or more recipients of Covered 215 | Software. However, You may do so only on Your own behalf, and not on 216 | behalf of any Contributor. You must make it absolutely clear that any 217 | such warranty, support, indemnity, or liability obligation is offered by 218 | You alone, and You hereby agree to indemnify every Contributor for any 219 | liability incurred by such Contributor as a result of warranty, support, 220 | indemnity or liability terms You offer. You may include additional 221 | disclaimers of warranty and limitations of liability specific to any 222 | jurisdiction. 223 | 224 | 4. Inability to Comply Due to Statute or Regulation 225 | 226 | If it is impossible for You to comply with any of the terms of this License 227 | with respect to some or all of the Covered Software due to statute, 228 | judicial order, or regulation then You must: (a) comply with the terms of 229 | this License to the maximum extent possible; and (b) describe the 230 | limitations and the code they affect. Such description must be placed in a 231 | text file included with all distributions of the Covered Software under 232 | this License. Except to the extent prohibited by statute or regulation, 233 | such description must be sufficiently detailed for a recipient of ordinary 234 | skill to be able to understand it. 235 | 236 | 5. Termination 237 | 238 | 5.1. The rights granted under this License will terminate automatically if You 239 | fail to comply with any of its terms. However, if You become compliant, 240 | then the rights granted under this License from a particular Contributor 241 | are reinstated (a) provisionally, unless and until such Contributor 242 | explicitly and finally terminates Your grants, and (b) on an ongoing 243 | basis, if such Contributor fails to notify You of the non-compliance by 244 | some reasonable means prior to 60 days after You have come back into 245 | compliance. Moreover, Your grants from a particular Contributor are 246 | reinstated on an ongoing basis if such Contributor notifies You of the 247 | non-compliance by some reasonable means, this is the first time You have 248 | received notice of non-compliance with this License from such 249 | Contributor, and You become compliant prior to 30 days after Your receipt 250 | of the notice. 251 | 252 | 5.2. If You initiate litigation against any entity by asserting a patent 253 | infringement claim (excluding declaratory judgment actions, 254 | counter-claims, and cross-claims) alleging that a Contributor Version 255 | directly or indirectly infringes any patent, then the rights granted to 256 | You by any and all Contributors for the Covered Software under Section 257 | 2.1 of this License shall terminate. 258 | 259 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user 260 | license agreements (excluding distributors and resellers) which have been 261 | validly granted by You or Your distributors under this License prior to 262 | termination shall survive termination. 263 | 264 | 6. Disclaimer of Warranty 265 | 266 | Covered Software is provided under this License on an "as is" basis, 267 | without warranty of any kind, either expressed, implied, or statutory, 268 | including, without limitation, warranties that the Covered Software is free 269 | of defects, merchantable, fit for a particular purpose or non-infringing. 270 | The entire risk as to the quality and performance of the Covered Software 271 | is with You. Should any Covered Software prove defective in any respect, 272 | You (not any Contributor) assume the cost of any necessary servicing, 273 | repair, or correction. This disclaimer of warranty constitutes an essential 274 | part of this License. No use of any Covered Software is authorized under 275 | this License except under this disclaimer. 276 | 277 | 7. Limitation of Liability 278 | 279 | Under no circumstances and under no legal theory, whether tort (including 280 | negligence), contract, or otherwise, shall any Contributor, or anyone who 281 | distributes Covered Software as permitted above, be liable to You for any 282 | direct, indirect, special, incidental, or consequential damages of any 283 | character including, without limitation, damages for lost profits, loss of 284 | goodwill, work stoppage, computer failure or malfunction, or any and all 285 | other commercial damages or losses, even if such party shall have been 286 | informed of the possibility of such damages. This limitation of liability 287 | shall not apply to liability for death or personal injury resulting from 288 | such party's negligence to the extent applicable law prohibits such 289 | limitation. Some jurisdictions do not allow the exclusion or limitation of 290 | incidental or consequential damages, so this exclusion and limitation may 291 | not apply to You. 292 | 293 | 8. Litigation 294 | 295 | Any litigation relating to this License may be brought only in the courts 296 | of a jurisdiction where the defendant maintains its principal place of 297 | business and such litigation shall be governed by laws of that 298 | jurisdiction, without reference to its conflict-of-law provisions. Nothing 299 | in this Section shall prevent a party's ability to bring cross-claims or 300 | counter-claims. 301 | 302 | 9. Miscellaneous 303 | 304 | This License represents the complete agreement concerning the subject 305 | matter hereof. If any provision of this License is held to be 306 | unenforceable, such provision shall be reformed only to the extent 307 | necessary to make it enforceable. Any law or regulation which provides that 308 | the language of a contract shall be construed against the drafter shall not 309 | be used to construe this License against a Contributor. 310 | 311 | 312 | 10. Versions of the License 313 | 314 | 10.1. New Versions 315 | 316 | Mozilla Foundation is the license steward. Except as provided in Section 317 | 10.3, no one other than the license steward has the right to modify or 318 | publish new versions of this License. Each version will be given a 319 | distinguishing version number. 320 | 321 | 10.2. Effect of New Versions 322 | 323 | You may distribute the Covered Software under the terms of the version 324 | of the License under which You originally received the Covered Software, 325 | or under the terms of any subsequent version published by the license 326 | steward. 327 | 328 | 10.3. Modified Versions 329 | 330 | If you create software not governed by this License, and you want to 331 | create a new license for such software, you may create and use a 332 | modified version of this License if you rename the license and remove 333 | any references to the name of the license steward (except to note that 334 | such modified license differs from this License). 335 | 336 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 337 | Licenses If You choose to distribute Source Code Form that is 338 | Incompatible With Secondary Licenses under the terms of this version of 339 | the License, the notice described in Exhibit B of this License must be 340 | attached. 341 | 342 | Exhibit A - Source Code Form License Notice 343 | 344 | This Source Code Form is subject to the 345 | terms of the Mozilla Public License, v. 346 | 2.0. If a copy of the MPL was not 347 | distributed with this file, You can 348 | obtain one at 349 | http://mozilla.org/MPL/2.0/. 350 | 351 | If it is not possible or desirable to put the notice in a particular file, 352 | then You may include the notice in a location (such as a LICENSE file in a 353 | relevant directory) where a recipient would be likely to look for such a 354 | notice. 355 | 356 | You may add additional accurate notices of copyright ownership. 357 | 358 | Exhibit B - "Incompatible With Secondary Licenses" Notice 359 | 360 | This Source Code Form is "Incompatible 361 | With Secondary Licenses", as defined by 362 | the Mozilla Public License, v. 2.0. 363 | 364 | -------------------------------------------------------------------------------- /MoebiusCodeDemoScreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/avaxman/MoebiusCode/deeaa8b935f234d2dd4da6d7857495efd4c7e49f/MoebiusCodeDemoScreen.png -------------------------------------------------------------------------------- /PrescribeEdgeJumps.h: -------------------------------------------------------------------------------- 1 | // 2 | // PrescribeEdgeJumps.h 3 | // testigl 4 | // 5 | // Created by Amir Vaxman on 22/12/14. 6 | // Copyright (c) 2014 Amir Vaxman. All rights reserved. 7 | // 8 | 9 | #ifndef MoebiusCode_PrescribeEdgeJumps_h 10 | #define MoebiusCode_PrescribeEdgeJumps_h 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | 18 | class PrescribeEdgeJumps3D{ 19 | public: 20 | 21 | Eigen::MatrixXi D, F; 22 | 23 | Eigen::MatrixXd OrigVq; 24 | Eigen::MatrixXi FaceCornerIndices; //rows of f1, f2, zi, zj (oriented) 25 | Eigen::VectorXd PresJumps; 26 | Eigen::VectorXd InitSolution; 27 | Eigen::VectorXd Firstcd; 28 | 29 | double PresFactor; 30 | double CloseFactor; 31 | double ConstTolerance; 32 | double SolutionSize; 33 | 34 | Eigen::RowVector4d UnitQuat; 35 | 36 | bool isExactMC; 37 | 38 | //intermediate variables 39 | Eigen::VectorXd PresVec; 40 | Eigen::VectorXd CloseVec; 41 | Eigen::VectorXd CompVec; 42 | Eigen::VectorXd ImagVec; 43 | Eigen::VectorXd FirstcdVec; 44 | Eigen::VectorXd MCVec; 45 | 46 | Eigen::VectorXd TotalVec; 47 | Eigen::VectorXd ConstVec; 48 | 49 | int PresTriOffset, PresRowOffset; 50 | int CloseTriOffset, CloseRowOffset; 51 | int CompTriOffset, CompRowOffset; 52 | int ImagTriOffset, ImagRowOffset; 53 | int FirstcdTriOffset, FirstcdRowOffset; 54 | int MCTriOffset, MCRowOffset; 55 | 56 | Eigen::VectorXi GradRows, GradCols; 57 | Eigen::VectorXd GradValues; 58 | 59 | void Initialize(const Eigen::MatrixXd& inOrigVq, 60 | const Eigen::MatrixXi& inD, 61 | const Eigen::MatrixXi& inF, 62 | Eigen::MatrixXi& inFaceCornerIndices, 63 | const bool& inisExactMC){ 64 | 65 | using namespace Eigen; 66 | using namespace std; 67 | F=inF; D=inD; 68 | FaceCornerIndices=inFaceCornerIndices; 69 | OrigVq=inOrigVq; 70 | isExactMC=inisExactMC; 71 | 72 | SolutionSize=2*4*F.rows(); 73 | 74 | UnitQuat<<1.0,0.0,0.0,0.0; 75 | 76 | PresVec.resize(4*2*FaceCornerIndices.rows()); 77 | CloseVec.resize(SolutionSize); 78 | CompVec.resize(4*FaceCornerIndices.rows()); 79 | ImagVec.resize(F.rows()); 80 | FirstcdVec.resize(8); 81 | Firstcd.resize(8); 82 | Firstcd<<0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0; 83 | 84 | 85 | if (isExactMC) 86 | MCVec.resize(2*FaceCornerIndices.rows()); 87 | else 88 | MCVec.resize(0); 89 | 90 | 91 | 92 | TotalVec.resize(PresVec.size()+CloseVec.size()+CompVec.size()+ImagVec.size()+FirstcdVec.size()+MCVec.size()); 93 | ConstVec.resize(CompVec.size()+ImagVec.size()+FirstcdVec.size()+MCVec.size()); 94 | 95 | ConstTolerance=10e-7; 96 | 97 | //***********************Creating Gradient Pattern**************************************/ 98 | 99 | if (!isExactMC){ 100 | GradRows.resize(128*FaceCornerIndices.rows()+SolutionSize+64*FaceCornerIndices.rows()+8*F.rows()+8); 101 | GradCols.resize(GradRows.size()); 102 | GradValues.resize(GradRows.size()); 103 | } //not currently doing exact MC error reproduction 104 | 105 | /**************************Prescription Energy*******************************/ 106 | PresTriOffset=0; 107 | PresRowOffset=0; 108 | Vector4i c1TriPoses; c1TriPoses<<0,16,32,48; 109 | Vector4i d1TriPoses; d1TriPoses<<4,20,36,52; 110 | Vector4i c2TriPoses; c2TriPoses<<8,24,40,56; 111 | Vector4i d2TriPoses; d2TriPoses<<12,28,44,60; 112 | int PresTriCounter=PresTriOffset; 113 | for (int i=0;i 336 | RowVector4d c=CurrSolution.segment(4*2*i,4); 337 | RowVector4d d=CurrSolution.segment(4*(2*i+1),4); 338 | 339 | for (int j=0;j<4;j++){ 340 | GradValues(ImagTriOffset+4*2*i+j)=d(j); 341 | GradValues(ImagTriOffset+4*(2*i+1)+j)=c(j); 342 | } 343 | } 344 | 345 | 346 | //firstcd is constant 347 | 348 | } 349 | 350 | void Reformulate(int CurrIter, int MaxIterations, const Eigen::VectorXd& CurrSolution, double PrevError) 351 | { 352 | using namespace Eigen; 353 | using namespace std; 354 | double rate=ConstVec.lpNorm()/PrevError; 355 | double ReduceRate=min(rate/2.0,1.0); 356 | 357 | InitSolution=CurrSolution; 358 | PresFactor*=0.75-0.25*(1.0-ReduceRate); 359 | 360 | } 361 | 362 | void UpdateConstraints(const Eigen::VectorXd& CurrSolution) 363 | { 364 | using namespace Eigen; 365 | using namespace std; 366 | for (int i=0;i() < ConstTolerance); 409 | } 410 | }; 411 | 412 | 413 | 414 | 415 | #endif 416 | -------------------------------------------------------------------------------- /QuadConstSolver.h: -------------------------------------------------------------------------------- 1 | // 2 | // QuadConstSolver.h 3 | // testigl 4 | // 5 | // Created by Amir Vaxman on 28/09/14. 6 | // Copyright (c) 2014 Amir Vaxman. All rights reserved. 7 | // 8 | 9 | #ifndef MoebiusCode_QuadConstSolver_h 10 | #define MoebiusCode_QuadConstSolver_h 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | template 19 | class QuadConstSolver{ 20 | private: 21 | QuadConstSolverTraits* SolverTraits; 22 | hedra::optimization::EigenSolverWrapper > > LinearSolver; 23 | public: 24 | 25 | Eigen::VectorXd ConvErrors; 26 | 27 | QuadConstSolver(){}; 28 | 29 | //returns M^T*M by (I,J,S) representation 30 | //prerequisite: iI are sorted by rows (not necessary columns) 31 | void MultiplyAdjointMatrix(const Eigen::VectorXi& iI, 32 | const Eigen::VectorXi& iJ, 33 | const Eigen::VectorXd& iS, 34 | Eigen::VectorXi& oI, 35 | Eigen::VectorXi& oJ, 36 | Eigen::VectorXd& oS) 37 | { 38 | int CurrTri=0; 39 | 40 | std::vector oIlist; 41 | std::vector oJlist; 42 | std::vector oSlist; 43 | do{ 44 | int CurrRow=iI(CurrTri); 45 | int NumCurrTris=0; 46 | while ((CurrTri+NumCurrTris=iJ(i)){ 52 | oIlist.push_back(iJ(i)); 53 | oJlist.push_back(iJ(j)); 54 | oSlist.push_back(iS(j)*iS(i)); 55 | } 56 | } 57 | } 58 | CurrTri+=NumCurrTris; 59 | }while (CurrTri!=iI.size()); 60 | 61 | oI.resize(oIlist.size()); 62 | oJ.resize(oJlist.size()); 63 | oS.resize(oSlist.size()); 64 | 65 | for (int i=0;iGradRows, st->GradCols,Eigen::VectorXd::Ones(st->GradRows.size()),I,J,S); 96 | 97 | LinearSolver.analyze(I,J, true); 98 | } 99 | 100 | Eigen::VectorXd Solve(const Eigen::VectorXd& InitSolution, 101 | double Inith, 102 | int MaxIterations){ 103 | 104 | using namespace Eigen; 105 | using namespace std; 106 | 107 | vector ConvErrorsList; 108 | 109 | VectorXd CurrSolution=InitSolution; 110 | int CurrIter=0; 111 | 112 | SolverTraits->UpdateEnergy(InitSolution); 113 | SolverTraits->UpdateGradient(InitSolution); 114 | 115 | cout<<"Initial Total Error: "<<(SolverTraits->TotalVec).template lpNorm()<ConstVec).template lpNorm()<ConstVec).template lpNorm(); 119 | ConvErrorsList.push_back(ConstError); 120 | 121 | bool isTerminate; 122 | double PrevConstError=32767.0; 123 | VectorXi MatRows, MatCols; 124 | VectorXd MatValues; 125 | VectorXd Rhs; 126 | MatrixXd Direction; 127 | do{ 128 | MultiplyAdjointMatrix(SolverTraits->GradRows, SolverTraits->GradCols,SolverTraits->GradValues, MatRows, MatCols, MatValues); 129 | MultiplyAdjointVector(SolverTraits->GradRows, SolverTraits->GradCols, SolverTraits->GradValues, -SolverTraits->TotalVec, Rhs); 130 | 131 | //solving to get the direction 132 | if(!LinearSolver.factorize(MatValues, true)) { 133 | // decomposition failed 134 | cout<<"Solver Failed to factorize! "<TotalVec).template lpNorm(); 146 | VectorXd CurrSolutionTest; 147 | double TestTotalError; 148 | do{ 149 | CurrSolutionTest=CurrSolution+h*Direction; 150 | SolverTraits->UpdateEnergy(CurrSolutionTest); 151 | TestTotalError=(SolverTraits->TotalVec).template lpNorm(); 152 | h*=0.5; 153 | }while ((TestTotalError>PrevTotalError)&&(h>10e-8)); 154 | 155 | CurrSolution=CurrSolutionTest; 156 | PrevConstError=ConstError; 157 | 158 | //assuming UpdateEnergy is already taken within the line search iteration 159 | ConstError=(SolverTraits->ConstVec).template lpNorm(); 160 | cout<<"Total Error:"<isTerminate(); 162 | if (isTerminate) 163 | cout<<"Terminating because Constraints are met!"<Reformulate(CurrIter, MaxIterations, CurrSolution, ConstError); 169 | ConvErrorsList.push_back(ConstError); 170 | SolverTraits->UpdateEnergy(CurrSolution); 171 | SolverTraits->UpdateGradient(CurrSolution); 172 | }while ((CurrIterUpdateEnergy(CurrSolution); 175 | double FinalTotalError=(SolverTraits->TotalVec).template lpNorm(); 176 | double FinalConstError=(SolverTraits->ConstVec).template lpNorm(); 177 | cout<<"Final Const Error:"< 15 | 16 | 17 | //both meshes have to be on the same unit sphere, 3 points interpolating, and the rest have the same radius 18 | class UnitSphereMoebiusTraitsTraits{ 19 | public: 20 | 21 | Matrix4d SourceVq; 22 | Matrix4d TargetVq; 23 | 24 | VectorXd InitSolution; 25 | double SolutionSize; 26 | 27 | double CloseFactor; 28 | double ConstTolerance; 29 | double ValueTolerance; 30 | 31 | RowVector4d UnitQuat; 32 | 33 | VectorXd CloseVec; 34 | VectorXd ImagVec; 35 | VectorXd PointVec; 36 | VectorXd UnitVec; 37 | 38 | VectorXd TotalVec; 39 | VectorXd ConstVec; 40 | 41 | VectorXi GradRows, GradCols; 42 | VectorXd GradValues; 43 | 44 | double CloseTriOffset, CloseRowOffset; 45 | double ImagTriOffset, ImagRowOffset; 46 | double PosTriOffset, PosRowOffset; 47 | double UnitTriOffset, UnitRowOffset; 48 | 49 | void Initialize(const Matrix4d& inSourceVq, const Matrix4d& inTargetVq, const VectorXd& inInitSolution){ 50 | 51 | 52 | InitSolution=inInitSolution; 53 | SourceVq=inSourceVq; 54 | TargetVq=inTargetVq; 55 | 56 | UnitQuat<<1.0,0.0,0.0,0.0; 57 | SolutionSize=16; 58 | 59 | CloseFactor=10e-6; 60 | ConstTolerance=10e-11; 61 | 62 | ImagVec.resize(6); 63 | PointVec.resize(4*3); 64 | UnitVec.resize(1); 65 | CloseVec.resize(SolutionSize); 66 | 67 | TotalVec.resize(CloseVec.size()+ImagVec.size()+PointVec.size()+UnitVec.size()); 68 | ConstVec.resize(ImagVec.size()+PointVec.size()+UnitVec.size()); 69 | 70 | //createing gradient pattern 71 | GradRows.resize(SolutionSize+(64+8+8)+64*3+SolutionSize); 72 | GradCols.resize(GradRows.size()); 73 | GradValues.resize(GradRows.size()); 74 | 75 | 76 | /*******************Closeness energy*************/ 77 | CloseTriOffset=0; 78 | CloseRowOffset=0; 79 | for (int i=0;i() 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | using namespace Eigen; 21 | using namespace std; 22 | 23 | 24 | igl::opengl::glfw::Viewer viewer; 25 | typedef enum {DC_ERROR, IA_ERROR, FACE_CONCYCLITY, QC_ERROR} ViewingModes; 26 | ViewingModes viewingMode=FACE_CONCYCLITY; 27 | 28 | bool showDeformed=true; 29 | std::vector handles; 30 | std::vector handlePoses; 31 | int currHandle; 32 | 33 | Eigen::MatrixXd origV, deformV, currV; 34 | Eigen::MatrixXd edgeOrigV, edgeDeformV; 35 | Eigen::MatrixXi F, edgeT, currT, polyT; 36 | Eigen::VectorXi D, polyTF,edgeTE, currTF; 37 | Eigen::MatrixXi EV, EF, FE, EFi, I4; 38 | Eigen::MatrixXd FEs; 39 | Eigen::VectorXi innerEdges; 40 | Eigen::Vector3d spans; 41 | bool isExactMC=false; 42 | bool isExactIAP=false; 43 | bool isQuat = false; 44 | std::string outputFileName; 45 | 46 | bool editing=false; 47 | bool choosingHandleMode=false; 48 | double currWinZ; 49 | hedra::ComplexMoebiusData cmdata; 50 | hedra::QuatMoebiusData qmdata; 51 | 52 | double rigidityFactor=0.1; //inversion control ratio 53 | double DCSensitivity=0.01; //ratio of abs(cr) 54 | double IASensitivity=1.0; //circle IA degrees difference between faces 55 | double QCSensitivity=0.2; //abs(max_sing/min_sing) 56 | double circSensitivity=5.0; //circle IA difference 57 | 58 | void choose_current_mesh(){ 59 | //choosing mesh 60 | switch(viewingMode){ 61 | case FACE_CONCYCLITY: 62 | case QC_ERROR: 63 | currV=(showDeformed ? deformV : origV); 64 | currT=polyT; 65 | currTF=polyTF; 66 | break; 67 | 68 | case DC_ERROR: 69 | case IA_ERROR: 70 | currV=(showDeformed ? edgeDeformV : edgeOrigV); 71 | currT=edgeT; 72 | currTF=edgeTE; 73 | break; 74 | } 75 | } 76 | 77 | bool UpdateCurrentView() 78 | { 79 | choose_current_mesh(); 80 | MatrixXd bc(handles.size(),currV.cols()); 81 | for (int i=0;i(Eigen::Vector3f(x,y,currWinZ), 157 | viewer.core().view, 158 | viewer.core().proj, 159 | viewer.core().viewport); 160 | 161 | handlePoses[handlePoses.size()-1]=NewPos.cast(); 162 | 163 | Eigen::MatrixXd A(3*F.rows(),3); 164 | for (int i=0;i(currV.row(CurrVertex).cast(), 224 | viewer.core().view, 225 | viewer.core().proj, 226 | viewer.core().viewport); 227 | 228 | currWinZ=WinCoords(2); 229 | std::cout<<"Choosing Vertex :"<0.01) DCSensitivity-=0.01; cout<<"discrete conformal error range: [0,"<1.0) IASensitivity-=1.0 ;cout<<"intersection-angle error range: [0,"<1.0) circSensitivity-=1.0 ;cout<<"concyclity error range: [0,"<0.05) QCSensitivity-=0.05 ;cout<<"quasiconformal error range: [0,"<10e-5) { //if it's a 2D mesh or not 351 | isQuat = true; 352 | rigidityFactor = 0.5; //initial 353 | } 354 | hedra::polygonal_edge_topology(D, F, EV, FE, EF,EFi,FEs,innerEdges); 355 | hedra::triangulate_mesh(D, F, polyT, polyTF); 356 | if (isQuat) 357 | hedra::quat_moebius_setup(origV,D,F,polyTF,EV,EF,EFi,FE,FEs, innerEdges, qmdata); 358 | else 359 | hedra::complex_moebius_setup(origV,D,F,polyTF,EV,EF,EFi,FE,FEs, innerEdges, cmdata); 360 | hedra::edge_mesh(origV, D, F, EV, EF, edgeOrigV, edgeT, edgeTE); 361 | 362 | currV=origV; 363 | deformV=origV; 364 | edgeDeformV=edgeOrigV; 365 | spans=currV.colwise().maxCoeff()-currV.colwise().minCoeff(); 366 | 367 | //handles mesh 368 | viewer.append_mesh(); 369 | 370 | 371 | viewer.callback_mouse_down = &mouse_down; 372 | viewer.callback_mouse_move = &mouse_move; 373 | viewer.callback_mouse_up=&mouse_up; 374 | viewer.callback_key_down=&key_down; 375 | viewer.callback_key_up=&key_up; 376 | viewer.core().background_color<<0.75,0.75,0.75,1.0; 377 | UpdateCurrentView(); 378 | viewer.launch(); 379 | } --------------------------------------------------------------------------------