From c3d0de5bda96594954df35c0f37e18fbae6d28d6 Mon Sep 17 00:00:00 2001
From: Heng Liu <liu@inf.unibe.ch>
Date: Thu, 8 Sep 2022 11:20:50 +0200
Subject: [PATCH] adapt to ovm3

---
 CMakeLists.txt                               |  19 +-
 cmake/FindEIGEN3.cmake                       |  70 -----
 cmake/SCOFDependencies.cmake                 |   8 +-
 cmake/SCOFDownloadExternal.cmake             |  18 +-
 src/SCOF/FrameFieldGeneratorT.hh             |   6 +-
 src/SCOF/MatchingsAndAlignmentExtractionT.cc |  16 +-
 src/SCOF/SingularityGraphT.cc                | 275 ++++++++++++++++---
 src/SCOF/Typedefs.hh                         |  14 +-
 8 files changed, 289 insertions(+), 137 deletions(-)
 delete mode 100644 cmake/FindEIGEN3.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 99a138a..289dcc9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,6 +16,11 @@
 
 cmake_minimum_required (VERSION 3.9)
 
+# AutoMOC/AutoUIC
+if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17")
+    cmake_policy(SET CMP0100 NEW)
+endif()
+
 list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
 
 project (SCOF
@@ -37,7 +42,7 @@ if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
     set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Build/lib")
     set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Build/lib")
 
-    set(CMAKE_CXX_STANDARD 14)
+    set(CMAKE_CXX_STANDARD 17)
 endif()
 
 set(SCOF_EXTERNAL "${CMAKE_CURRENT_SOURCE_DIR}/external")
@@ -101,7 +106,7 @@ target_compile_definitions(SCOF
 set_target_properties(SCOF PROPERTIES
         VERSION ${SCOF_VERSION_MAJOR}.${SCOF_VERSION_MINOR}
         SOVERSION ${SCOF_VERSION_MAJOR}.${SCOF_VERSION_MINOR}
-        CXX_STANDARD 14
+        CXX_STANDARD 17
         CXX_STANDARD_REQUIRED YES
         CXX_EXTENSIONS NO
         CXX_VISIBILITY_PRESET hidden
@@ -133,6 +138,7 @@ if(CHOLMOD_INCLUDES)
             OpenMeshCore
             OpenMeshTools
             OpenVolumeMesh::OpenVolumeMesh
+            Eigen3::Eigen
             ${CHOLMOD_LIBRARIES}
             )
     #Set target properties
@@ -143,7 +149,7 @@ if(CHOLMOD_INCLUDES)
             $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
             #    PRIVATE
             #"${CMAKE_CURRENT_BINARY_DIR}/src"
-            ${EIGEN3_INCLUDE_DIR}
+#            ${EIGEN3_INCLUDE_DIR}
             ${GMM_INCLUDE_DIR}
             ${CHOLMOD_INCLUDES}
             )
@@ -152,6 +158,7 @@ else(CHOLMOD_INCLUDES)
             OpenMeshCore
             OpenMeshTools
             OpenVolumeMesh::OpenVolumeMesh
+            Eigen3::Eigen
             )
     #Set target properties
     target_include_directories(SCOF
@@ -162,10 +169,14 @@ else(CHOLMOD_INCLUDES)
             #    PRIVATE
             #"${CMAKE_CURRENT_BINARY_DIR}/src"
             ${GMM_INCLUDE_DIR}
-            ${EIGEN3_INCLUDE_DIR}
+#            ${EIGEN3_INCLUDE_DIR}
             )
 endif()
 
+#If set found by upper level, eigen needs it to compile
+if(OpenMP_CXX_FOUND)
+    target_link_libraries(SCOF PUBLIC OpenMP::OpenMP_CXX OpenMP::OpenMP_C)
+endif()
 
 if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
     add_subdirectory(demo/scof)
diff --git a/cmake/FindEIGEN3.cmake b/cmake/FindEIGEN3.cmake
deleted file mode 100644
index fa8fc4f..0000000
--- a/cmake/FindEIGEN3.cmake
+++ /dev/null
@@ -1,70 +0,0 @@
-# - Try to find EIGEN3
-# Once done this will define
-#  EIGEN3_FOUND         - System has EIGEN3
-#  EIGEN3_INCLUDE_DIRS  - The EIGEN3 include directories
-
-if (EIGEN3_INCLUDE_DIR)
-  # in cache already
-  set(EIGEN3_FOUND TRUE)
-  set(EIGEN3_INCLUDE_DIRS "${EIGEN3_INCLUDE_DIR}" )
-else (EIGEN3_INCLUDE_DIR)
-
-# Check if the base path is set
-if ( NOT CMAKE_WINDOWS_LIBS_DIR )
-  # This is the base directory for windows library search used in the finders we shipp.
-  set(CMAKE_WINDOWS_LIBS_DIR "c:/libs" CACHE STRING "Default Library search dir on windows." )
-endif()
-
-if ( CMAKE_GENERATOR MATCHES "^Visual Studio 11.*Win64" )
-  SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2012/x64/")
-elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 11.*" )
-  SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2012/x32/")
-elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 12.*Win64" )
-  SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2013/x64/")
-elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 12.*" )
-  SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2013/x32/")
-elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 14.*Win64" )
-  SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2015/x64/")
-elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 14.*" )
-  SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2015/x32/")
-elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 15.*Win64" )
-  SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2017/x64/")
-elseif ( CMAKE_GENERATOR MATCHES "^Visual Studio 15.*" )
-  SET(VS_SEARCH_PATH "${CMAKE_WINDOWS_LIBS_DIR}/vs2017/x32/")
-endif()
-
-
-find_path( EIGEN3_INCLUDE_DIR 
-	   NAMES Eigen/Dense 
-           PATHS $ENV{EIGEN_DIR}
-                 /usr/include/eigen3
-                 /usr/local/include
-                 /usr/local/include/eigen3/
-                 /opt/local/include/eigen3/
-                 "${CMAKE_WINDOWS_LIBS_DIR}/general/Eigen-3.3.4"
-                 "${CMAKE_WINDOWS_LIBS_DIR}/general/Eigen-3.2.8"
-                 "${CMAKE_WINDOWS_LIBS_DIR}/general/Eigen-3.2.6"
-                 "${CMAKE_WINDOWS_LIBS_DIR}/Eigen-3.2.6"
-                 "${CMAKE_WINDOWS_LIBS_DIR}/Eigen-3.2.6/include"
-                 "${CMAKE_WINDOWS_LIBS_DIR}/Eigen-3.2.1"
-                 "${CMAKE_WINDOWS_LIBS_DIR}/Eigen-3.2.1/include"
-                 "${CMAKE_WINDOWS_LIBS_DIR}/Eigen-3.2/include"
-                 "${CMAKE_WINDOWS_LIBS_DIR}/eigen3/include"
-                 "${CMAKE_WINDOWS_LIBS_DIR}/eigen/include"
-                 ${PROJECT_SOURCE_DIR}/MacOS/Libs/eigen3/include
-                 ../../External/include
-                 ${module_file_path}/../../../External/include
-          )
-
-set(EIGEN3_INCLUDE_DIRS "${EIGEN3_INCLUDE_DIR}" )
-
-
-include(FindPackageHandleStandardArgs)
-# handle the QUIETLY and REQUIRED arguments and set LIBCPLEX_FOUND to TRUE
-# if all listed variables are TRUE
-find_package_handle_standard_args(EIGEN3  DEFAULT_MSG
-                                  EIGEN3_INCLUDE_DIR)
-
-mark_as_advanced(EIGEN3_INCLUDE_DIR)
-
-endif(EIGEN3_INCLUDE_DIR)
diff --git a/cmake/SCOFDependencies.cmake b/cmake/SCOFDependencies.cmake
index eee4d0c..3d0c6d6 100644
--- a/cmake/SCOFDependencies.cmake
+++ b/cmake/SCOFDependencies.cmake
@@ -21,9 +21,15 @@ if(NOT TARGET OpenVolumeMesh::OpenVolumeMesh)
 endif()
 
 
+## Eigen
+#find_package(EIGEN3)
+#if(NOT EIGEN3_FOUND AND "${CMAKE_PROJECT_NAME}" STREQUAL "SCOF")
+#    scof_download_eigen()
+#endif()
+
 # Eigen
 find_package(EIGEN3)
-if(NOT EIGEN3_FOUND AND "${CMAKE_PROJECT_NAME}" STREQUAL "SCOF")
+if(NOT TARGET Eigen3::Eigen)
     scof_download_eigen()
 endif()
 
diff --git a/cmake/SCOFDownloadExternal.cmake b/cmake/SCOFDownloadExternal.cmake
index 936d1ed..1a8c729 100644
--- a/cmake/SCOFDownloadExternal.cmake
+++ b/cmake/SCOFDownloadExternal.cmake
@@ -41,7 +41,7 @@ endfunction()
 function(scof_download_openvolumemesh)
     scof_download_project(OpenVolumeMesh
         GIT_REPOSITORY       https://www.graphics.rwth-aachen.de:9000/OpenVolumeMesh/OpenVolumeMesh.git
-        GIT_TAG              cgg
+        GIT_TAG              master
         )
     if (${SCOF_DOWNLOAD_MISSINGS_DEPS})
         add_subdirectory(${SCOF_EXTERNAL}/OpenVolumeMesh)
@@ -60,12 +60,24 @@ function(scof_download_eigen)
     endif()
 endfunction()
 
+## Eigen
+function(scof_download_eigen)
+    scof_download_project(eigen
+            GIT_REPOSITORY      https://gitlab.com/libeigen/eigen.git
+            GIT_TAG             master
+            )
+    add_library (Eigen3::Eigen INTERFACE IMPORTED)
+    target_include_directories (Eigen3::Eigen SYSTEM INTERFACE $<BUILD_INTERFACE:${SCOF_EXTERNAL}/eigen>)
+    #    target_include_directories (Eigen3::Eigen SYSTEM INTERFACE "${ALGOHEX_EXTERNAL}/eigen")
+    target_compile_definitions(Eigen3::Eigen INTERFACE -DEIGEN_HAS_STD_RESULT_OF=0)
+endfunction()
+
 
 ## GMM
 function(scof_download_gmm)
     scof_download_project(gmm
-            URL           http://download-mirror.savannah.gnu.org/releases/getfem/stable/gmm-5.3.tar.gz
-            URL_HASH SHA256=86ac46d69982afd9bc0d032788ae6ab81eab8118df1012690b1c2501ec687252
+            URL           http://download-mirror.savannah.gnu.org/releases/getfem/stable/gmm-5.4.tar.gz
+            URL_HASH SHA256=7163d5080efbe6893d1950e4b331cd3e9160bb3dcf583d206920fba6af7b1e56
             )
     if (${SCOF_DOWNLOAD_MISSINGS_DEPS})
         set(GMM_INCLUDE_DIR $<BUILD_INTERFACE:${SCOF_EXTERNAL}/gmm/include> PARENT_SCOPE)
diff --git a/src/SCOF/FrameFieldGeneratorT.hh b/src/SCOF/FrameFieldGeneratorT.hh
index 421fc9c..0d19f9e 100644
--- a/src/SCOF/FrameFieldGeneratorT.hh
+++ b/src/SCOF/FrameFieldGeneratorT.hh
@@ -18,11 +18,11 @@
 #include <iomanip>
 #include <float.h>
 
-#include <Eigen/Dense>
-#include <Eigen/Sparse>
+#include <Eigen/Core>
+#include <Eigen/SparseCore>
 
 #include <OpenVolumeMesh/Mesh/TetrahedralMesh.hh>
-#include <OpenVolumeMesh/Core/PropertyDefines.hh>
+#include <OpenVolumeMesh/Core/Properties/PropertyPtr.hh>
 #include <OpenVolumeMesh/Mesh/TetrahedralGeometryKernel.hh>
 
 #include "TransitionQuaternionEigen.hh"
diff --git a/src/SCOF/MatchingsAndAlignmentExtractionT.cc b/src/SCOF/MatchingsAndAlignmentExtractionT.cc
index 332c21c..48c99f2 100644
--- a/src/SCOF/MatchingsAndAlignmentExtractionT.cc
+++ b/src/SCOF/MatchingsAndAlignmentExtractionT.cc
@@ -201,7 +201,7 @@ add_corner_constraints(std::map<EH, std::vector<int> >& _eh_to_corners)
 		std::shared_ptr<CornerT<TetMesh> > corner(new CornerT<TetMesh>());
 		for(int j=0; j<3; ++j)
 		{
-			HEH hej = mesh_.halfedge(corner_vt_prop[OVM::MeshHandle(0)][4*i], corner_vt_prop[OVM::MeshHandle(0)][4*i+j+1]);
+			HEH hej = mesh_.find_halfedge(corner_vt_prop[OVM::MeshHandle(0)][4*i], corner_vt_prop[OVM::MeshHandle(0)][4*i+j+1]);
 			corner.get()->set_ith_halfedge(j, hej);
 			corner.get()->set_ith_dual_path(j, dp_prop[OVM::MeshHandle(0)][3*i+j]);
 		}
@@ -286,7 +286,7 @@ add_tangent_continuity_constraints()
 			std::shared_ptr<TangentContinuityT<TetMesh> > tc(new TangentContinuityT<TetMesh>());
 			for(int j=0; j<2; ++j)
 			{
-				HEH hej = mesh_.halfedge(tc_vt_prop[OVM::MeshHandle(0)][3*i], tc_vt_prop[OVM::MeshHandle(0)][3*i+j+1]);
+				HEH hej = mesh_.find_halfedge(tc_vt_prop[OVM::MeshHandle(0)][3*i], tc_vt_prop[OVM::MeshHandle(0)][3*i+j+1]);
 				tc.get()->set_ith_halfedge(j, hej);
 			}
 			tc.get()->set_dual_path(tc_dp_prop[OVM::MeshHandle(0)][i]);
@@ -1509,12 +1509,12 @@ cell_edges(const CH _ch, std::vector<EH>& _ehs)const
 {
 	std::vector<VH> vhs = mesh_.get_cell_vertices(_ch);
 
-	_ehs.push_back(mesh_.edge_handle(mesh_.halfedge(vhs[0], vhs[1])));
-	_ehs.push_back(mesh_.edge_handle(mesh_.halfedge(vhs[0], vhs[2])));
-	_ehs.push_back(mesh_.edge_handle(mesh_.halfedge(vhs[0], vhs[3])));
-	_ehs.push_back(mesh_.edge_handle(mesh_.halfedge(vhs[1], vhs[2])));
-	_ehs.push_back(mesh_.edge_handle(mesh_.halfedge(vhs[1], vhs[3])));
-	_ehs.push_back(mesh_.edge_handle(mesh_.halfedge(vhs[2], vhs[3])));
+	_ehs.push_back(mesh_.edge_handle(mesh_.find_halfedge(vhs[0], vhs[1])));
+	_ehs.push_back(mesh_.edge_handle(mesh_.find_halfedge(vhs[0], vhs[2])));
+	_ehs.push_back(mesh_.edge_handle(mesh_.find_halfedge(vhs[0], vhs[3])));
+	_ehs.push_back(mesh_.edge_handle(mesh_.find_halfedge(vhs[1], vhs[2])));
+	_ehs.push_back(mesh_.edge_handle(mesh_.find_halfedge(vhs[1], vhs[3])));
+	_ehs.push_back(mesh_.edge_handle(mesh_.find_halfedge(vhs[2], vhs[3])));
 }
 
 
diff --git a/src/SCOF/SingularityGraphT.cc b/src/SCOF/SingularityGraphT.cc
index 5563c50..0c01b05 100644
--- a/src/SCOF/SingularityGraphT.cc
+++ b/src/SCOF/SingularityGraphT.cc
@@ -159,7 +159,7 @@ set_singularity_graph_component_property()
 			if(is_boundary_curve)//TODO: more careful on what is boundary curve
 //		if(mesh_.is_boundary(curve_ehs[0]))
 			{
-				HEH he = mesh_.halfedge(curve_vhs[0], curve_vhs[curve_vhs.size()-1]);
+				HEH he = mesh_.find_halfedge(curve_vhs[0], curve_vhs[curve_vhs.size()-1]);
 				//boundary circle
 				if(he.is_valid())
 					for(auto i : curve_ehs)
@@ -180,7 +180,7 @@ set_singularity_graph_component_property()
 				}else if(curve_vhs.size() > 2)
 				{
 					int type = 0;
-					HEH he = mesh_.halfedge(curve_vhs[0], curve_vhs[curve_vhs.size()-1]);
+					HEH he = mesh_.find_halfedge(curve_vhs[0], curve_vhs[curve_vhs.size()-1]);
 					//interior singular arc touches the boundary
 					if(!he.is_valid() && mesh_.is_boundary(curve_vhs[0]) && mesh_.is_boundary(curve_vhs[curve_vhs.size()-1]))
 						type = -2;
@@ -285,7 +285,7 @@ set_singularity_graph_component_property()
 	{
 	    for(const auto vhi : mesh_.vertices()) {
 	        int idx = node_index(vhi);
-            node_type_[vhi] = node_index(vhi);
+            node_type_[vhi] = idx;
             if(idx == 20 || idx == 10)
 	            std::cout<<"ERROR: Wrong Interior Singularity Node Type! Vertex: "<<vhi<<std::endl;
         }
@@ -297,20 +297,44 @@ set_singularity_graph_component_property()
     int
     SingularityGraphT<MeshT>::node_index(const VH& _vh) const {
         if (!mesh_.is_boundary(_vh)) {
-            int n_val_ng1_i = 0, n_val1_i = 0, n_complex = 0;
+            int n_all = 0, n_val_ng1_i = 0, n_val1_i = 0, n_val_ng2_i = 0, n_val2_i = 0, n_val3_i = 0, n_val4_i = 0, n_complex = 0;
             for (auto voh_it = mesh_.voh_iter(_vh); voh_it.valid(); ++voh_it) {
                 auto eh = mesh_.edge_handle(*voh_it);
                 if (valence_[eh] == -1)
                     n_val_ng1_i++;
                 else if (valence_[eh] == 1)
                     n_val1_i++;
+                else if (valence_[eh] == -2)
+                    n_val_ng2_i++;
+                else if (valence_[eh] == 2)
+                    n_val2_i++;
+                else if (valence_[eh] == 3)
+                    n_val3_i++;
+                else if (valence_[eh] == 4)
+                    n_val4_i++;
                 else if (valence_[eh] != 0)
                     n_complex++;
+
+                if(valence_[eh] != 0)
+                    n_all++;
             }
 
             if (n_complex > 0)
                 return 20;
 
+            if(n_val_ng2_i != 0 || n_val2_i != 0 || n_val3_i != 0 || n_val4_i != 0) {
+                if (n_val_ng1_i == 0 && n_val1_i == 0 && n_val_ng2_i == 0 && n_val2_i == 2)
+                    return 0;
+                else if (n_val_ng1_i == 0 && n_val1_i == 0 && n_val_ng2_i == 2 && n_val2_i == 0)
+                    return 0;
+                else if (n_all == 2 && n_val3_i == 2)
+                    return 0;
+                else if (n_all == 2 && n_val4_i == 2)
+                    return 0;
+                else
+                    return 20;
+            }
+
             if ((n_val_ng1_i == 0 && n_val1_i == 0) || (n_val_ng1_i == 2 && n_val1_i == 0) ||
                 (n_val_ng1_i == 0 && n_val1_i == 2))
                 return 0;
@@ -322,13 +346,21 @@ set_singularity_graph_component_property()
                 return 3;
             else if (n_val_ng1_i == 0 && n_val1_i == 4)
                 return 4;
+            else if (n_val_ng1_i == 2 && n_val1_i == 6)
+                return 5;
+            else if (n_val_ng1_i == 0 && n_val1_i == 6)
+                return 6;
+            else if (n_val_ng1_i == 0 && n_val1_i == 8)
+                return 7;
+            else if (n_val_ng1_i == 0 && n_val1_i == 12)
+                return 8;
             else if (n_val_ng1_i == 1 && n_val1_i == 1) {
                 return 10;
             } else
                 return 20;
         } else {
-            int n_val_ng1_b = 0, n_val1_b = 0,
-                    n_val_ng1_i = 0, n_val1_i = 0, n_complex = 0;
+            int n_all = 0, n_val_ng1_b = 0, n_val_ng2_b = 0, n_val1_b = 0, n_val2_b = 0,
+                    n_val2_i = 0, n_val3_i = 0, n_val4_i = 0, n_val_ng2_i = 0, n_val_ng1_i = 0, n_val1_i = 0, n_complex = 0;
             for (auto voh_it = mesh_.voh_iter(_vh); voh_it.valid(); ++voh_it) {
                 EH eh = mesh_.edge_handle(*voh_it);
                 if (mesh_.is_boundary(eh)) {
@@ -336,59 +368,212 @@ set_singularity_graph_component_property()
                         n_val_ng1_b++;
                     else if (valence_[eh] == 1)
                         n_val1_b++;
-                    else if (valence_[eh] != 0)
-                        n_complex++;
+                    else if (valence_[eh] == -2)
+                        n_val_ng2_b++;
+                    else if (valence_[eh] == 2)
+                        n_val2_b++;
                 } else {
                     if (valence_[eh] == -1)
                         n_val_ng1_i++;
                     else if (valence_[eh] == 1)
                         n_val1_i++;
+                    else if (valence_[eh] == -2)
+                        n_val_ng2_i++;
+                    else if (valence_[eh] == 2)
+                        n_val2_i++;
+                    else if (valence_[eh] == 3)
+                        n_val3_i++;
+                    else if (valence_[eh] == 4)
+                        n_val4_i++;
                     else if (valence_[eh] != 0)
                         n_complex++;
                 }
+
+                if(valence_[eh] != 0)
+                    n_all++;
             }
 
             if (n_complex > 0)
                 return 20;
 
+            if(n_val_ng2_i != 0 || n_val2_i != 0 || n_val3_i != 0 || n_val4_i != 0) {
+                if (n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 0 &&
+                    n_val_ng2_b == 0 && n_val2_b == 0 && n_val_ng2_i == 1 && n_val2_i == 0)
+                    return -10;
+                else if (n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 0 &&
+                         n_val_ng2_b == 0 && n_val2_b == 0 && n_val_ng2_i == 0 && n_val2_i == 1)
+                    return -11;
+                else if (n_all == 1 && n_val3_i == 1) // only enumerate simple case
+                    return -18;
+                else if (n_all == 1 && n_val4_i == 1) // only enumerate simple case
+                    return -19;
+                else
+                    return 20;
+            }
+
             //all cases that num_sge <=4
-            if (((n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 0) ||
-                 (n_val_ng1_b == 2 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 0) ||
-                 (n_val_ng1_b == 0 && n_val1_b == 2 && n_val_ng1_i == 0 && n_val1_i == 0)))
-                return 0;
-            else if ((n_val_ng1_b == 3 && n_val1_b == 0) && n_val_ng1_i == 0 && n_val1_i == 0)
-                return -1;
-            else if ((n_val_ng1_b == 2 && n_val1_b == 1) && n_val_ng1_i == 0 && n_val1_i == 0)
-                return -2;
-            else if ((n_val_ng1_b == 2 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 0)
-                return -3; // -4 has the same number, but it's a mirror case
-            else if ((n_val_ng1_b == 0 && n_val1_b == 3) && n_val_ng1_i == 0 && n_val1_i == 1)
-                return -5;
-            else if ((n_val_ng1_b == 1 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 0)
-                return -6;
-            else if ((n_val_ng1_b == 0 && n_val1_b == 3) && n_val_ng1_i == 0 && n_val1_i == 0)
-                return -7;
-            else if ((n_val_ng1_b == 1 && n_val1_b == 2) && n_val_ng1_i == 1 && n_val1_i == 0)
-                return -8;
-                //this could be an invalid case if the interior arc goes in the wrong direction
-            else if ((n_val_ng1_b == 0 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 1)
-                return -9;
-            else if (n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng1_i == 1 && n_val1_i == 0)
-                return -10;
-            else if (n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 1)
-                return -11;
-                //this could be an invalid case if the interior arc goes in the wrong direction
-            else if (n_val_ng1_b == 0 && n_val1_b == 2 && n_val_ng1_i == 1 && n_val1_i == 0)
-                return -12;
-            else if (n_val_ng1_b == 0 && n_val1_b == 2 && n_val_ng1_i == 1 && n_val1_i == 1)
-                return -13;
-            else if ((n_val_ng1_b == 1 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 1)
-                return -14;
-            else if ((n_val_ng1_b == 1 && n_val1_b == 1) && n_val_ng1_i == 0 && n_val1_i == 0)
-                return 10;
-            else
+//                if(n_val_ng1_i == 0 && n_val1_i == 0) {
+//                    if((n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng2_b == 0 && n_val2_b == 0) ||
+//                       (n_val_ng1_b == 2 && n_val1_b == 0 && n_val_ng2_b == 0 && n_val2_b == 0) ||
+//                       (n_val_ng1_b == 0 && n_val1_b == 2 && n_val_ng2_b == 0 && n_val2_b == 0) ||
+//                       (n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng2_b == 2 && n_val2_b == 0) ||
+//                       (n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng2_b == 0 && n_val2_b == 2))
+//                        return 0;
+//                }
+            if(n_val_ng2_b == 0 && n_val2_b == 0) {
+                if (((n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 0) ||
+                     (n_val_ng1_b == 2 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 0) ||
+                     (n_val_ng1_b == 0 && n_val1_b == 2 && n_val_ng1_i == 0 && n_val1_i == 0)))
+                    return 0;
+                else if ((n_val_ng1_b == 3 && n_val1_b == 0) && n_val_ng1_i == 0 && n_val1_i == 0)
+                    return -1;
+                else if ((n_val_ng1_b == 2 && n_val1_b == 1) && n_val_ng1_i == 0 && n_val1_i == 0)
+                    return -2;
+                else if ((n_val_ng1_b == 2 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 0)
+                    return -3; // -4 has the same number, but it's a mirror case
+                else if ((n_val_ng1_b == 0 && n_val1_b == 3) && n_val_ng1_i == 0 && n_val1_i == 1)
+                    return -5;
+                else if ((n_val_ng1_b == 1 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 0)
+                    return -6;
+                else if ((n_val_ng1_b == 0 && n_val1_b == 3) && n_val_ng1_i == 0 && n_val1_i == 0)
+                    return -7;
+                else if ((n_val_ng1_b == 1 && n_val1_b == 2) && n_val_ng1_i == 1 && n_val1_i == 0)
+                    return -8;
+                    //this could be an invalid case if the interior arc goes in the wrong direction
+                else if ((n_val_ng1_b == 0 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 1)
+                    return -9;
+                else if (n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng1_i == 1 && n_val1_i == 0)
+                    return -10;
+                else if (n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 1)
+                    return -11;
+                    //this could be an invalid case if the interior arc goes in the wrong direction
+                else if (n_val_ng1_b == 0 && n_val1_b == 2 && n_val_ng1_i == 1 && n_val1_i == 0)
+                    return -12;
+                else if (n_val_ng1_b == 0 && n_val1_b == 2 && n_val_ng1_i == 1 && n_val1_i == 1)
+                    return -13;
+                else if ((n_val_ng1_b == 1 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 1)
+                    return -14;
+                else if (((n_val_ng1_b == 1 && n_val1_b == 1) && n_val_ng1_i == 0 && n_val1_i == 0) ||
+                         ((n_val_ng1_b == 1 && n_val1_i == 1) && n_val_ng1_i == 0 && n_val1_b == 0) ||
+                         ((n_val_ng1_i == 1 && n_val1_b == 1) && n_val_ng1_b == 0 && n_val1_i == 0))
+                    return 10;
+                else
+                    return 20;
+            } else {//valence +2
+                if(n_val_ng1_i == 0 && n_val1_i == 0 && n_val_ng1_b == 0 && n_val1_b == 0) {
+                    if ((n_val_ng2_b == 2 && n_val2_b == 0) ||
+                        (n_val_ng2_b == 0 && n_val2_b == 2)) {
+                        return 0;
+                    }
+                }
+
+                //two 0-sector touch
+                if(n_val_ng2_b == 0 && n_val2_b == 1 && n_val_ng1_b == 2 && n_val1_b == 2 && n_val_ng1_i == 0 && n_val1_i == 0)
+                    return -15;
+
+                if(n_val_ng2_b == 0 && n_val2_b == 1 && n_val_ng1_b == 2 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 0)
+                    return -16;
+
+                if(n_val_ng2_b == 0 && n_val2_b == 1 && n_val_ng1_b == 0 && n_val1_b == 2 && n_val_ng1_i == 0 && n_val1_i == 0)
+                    return -17;
+
                 return 20;
+            }
         }
+
+//        if (!mesh_.is_boundary(_vh)) {
+//            int n_val_ng1_i = 0, n_val1_i = 0, n_complex = 0;
+//            for (auto voh_it = mesh_.voh_iter(_vh); voh_it.valid(); ++voh_it) {
+//                auto eh = mesh_.edge_handle(*voh_it);
+//                if (valence_[eh] == -1)
+//                    n_val_ng1_i++;
+//                else if (valence_[eh] == 1)
+//                    n_val1_i++;
+//                else if (valence_[eh] != 0)
+//                    n_complex++;
+//            }
+//
+//            if (n_complex > 0)
+//                return 20;
+//
+//            if ((n_val_ng1_i == 0 && n_val1_i == 0) || (n_val_ng1_i == 2 && n_val1_i == 0) ||
+//                (n_val_ng1_i == 0 && n_val1_i == 2))
+//                return 0;
+//            else if (n_val_ng1_i == 4 && n_val1_i == 0)
+//                return 1;
+//            else if (n_val_ng1_i == 2 && n_val1_i == 2)
+//                return 2;
+//            else if (n_val_ng1_i == 1 && n_val1_i == 3)
+//                return 3;
+//            else if (n_val_ng1_i == 0 && n_val1_i == 4)
+//                return 4;
+//            else if (n_val_ng1_i == 1 && n_val1_i == 1) {
+//                return 10;
+//            } else
+//                return 20;
+//        } else {
+//            int n_val_ng1_b = 0, n_val1_b = 0,
+//                    n_val_ng1_i = 0, n_val1_i = 0, n_complex = 0;
+//            for (auto voh_it = mesh_.voh_iter(_vh); voh_it.valid(); ++voh_it) {
+//                EH eh = mesh_.edge_handle(*voh_it);
+//                if (mesh_.is_boundary(eh)) {
+//                    if (valence_[eh] == -1)
+//                        n_val_ng1_b++;
+//                    else if (valence_[eh] == 1)
+//                        n_val1_b++;
+//                    else if (valence_[eh] != 0)
+//                        n_complex++;
+//                } else {
+//                    if (valence_[eh] == -1)
+//                        n_val_ng1_i++;
+//                    else if (valence_[eh] == 1)
+//                        n_val1_i++;
+//                    else if (valence_[eh] != 0)
+//                        n_complex++;
+//                }
+//            }
+//
+//            if (n_complex > 0)
+//                return 20;
+//
+//            //all cases that num_sge <=4
+//            if (((n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 0) ||
+//                 (n_val_ng1_b == 2 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 0) ||
+//                 (n_val_ng1_b == 0 && n_val1_b == 2 && n_val_ng1_i == 0 && n_val1_i == 0)))
+//                return 0;
+//            else if ((n_val_ng1_b == 3 && n_val1_b == 0) && n_val_ng1_i == 0 && n_val1_i == 0)
+//                return -1;
+//            else if ((n_val_ng1_b == 2 && n_val1_b == 1) && n_val_ng1_i == 0 && n_val1_i == 0)
+//                return -2;
+//            else if ((n_val_ng1_b == 2 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 0)
+//                return -3; // -4 has the same number, but it's a mirror case
+//            else if ((n_val_ng1_b == 0 && n_val1_b == 3) && n_val_ng1_i == 0 && n_val1_i == 1)
+//                return -5;
+//            else if ((n_val_ng1_b == 1 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 0)
+//                return -6;
+//            else if ((n_val_ng1_b == 0 && n_val1_b == 3) && n_val_ng1_i == 0 && n_val1_i == 0)
+//                return -7;
+//            else if ((n_val_ng1_b == 1 && n_val1_b == 2) && n_val_ng1_i == 1 && n_val1_i == 0)
+//                return -8;
+//                //this could be an invalid case if the interior arc goes in the wrong direction
+//            else if ((n_val_ng1_b == 0 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 1)
+//                return -9;
+//            else if (n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng1_i == 1 && n_val1_i == 0)
+//                return -10;
+//            else if (n_val_ng1_b == 0 && n_val1_b == 0 && n_val_ng1_i == 0 && n_val1_i == 1)
+//                return -11;
+//                //this could be an invalid case if the interior arc goes in the wrong direction
+//            else if (n_val_ng1_b == 0 && n_val1_b == 2 && n_val_ng1_i == 1 && n_val1_i == 0)
+//                return -12;
+//            else if (n_val_ng1_b == 0 && n_val1_b == 2 && n_val_ng1_i == 1 && n_val1_i == 1)
+//                return -13;
+//            else if ((n_val_ng1_b == 1 && n_val1_b == 2) && n_val_ng1_i == 0 && n_val1_i == 1)
+//                return -14;
+//            else if ((n_val_ng1_b == 1 && n_val1_b == 1) && n_val_ng1_i == 0 && n_val1_i == 0)
+//                return 10;
+//            else
+//                return 20;
+//        }
     }
 
 
@@ -586,9 +771,9 @@ set_singularity_graph_component_property()
         sort_vertices_on_curve(_label, vhs);
 
         for(size_t i=0; i<vhs.size()-1; ++i)
-            _hes.push_back(mesh_.halfedge(vhs[i], vhs[i+1]));
+            _hes.push_back(mesh_.find_halfedge(vhs[i], vhs[i+1]));
 
-        auto he = mesh_.halfedge(vhs[vhs.size()-1], vhs[0]);
+        auto he = mesh_.find_halfedge(vhs[vhs.size()-1], vhs[0]);
         if(he.is_valid() && vhs.size() > 2 && label_[mesh_.edge_handle(he)] == _label)
             _hes.push_back(he);
     }
diff --git a/src/SCOF/Typedefs.hh b/src/SCOF/Typedefs.hh
index 188f4e2..0002fe3 100644
--- a/src/SCOF/Typedefs.hh
+++ b/src/SCOF/Typedefs.hh
@@ -6,10 +6,18 @@
  */
 #pragma once
 
-#include <OpenVolumeMesh/Core/OpenVolumeMeshHandle.hh>
+//#include <OpenVolumeMesh/Core/OpenVolumeMeshHandle.hh>
+//#include <OpenVolumeMesh/Core/BaseEntities.hh>
+//#include <OpenVolumeMesh/Core/PropertyPtr.hh>
+//#include <OpenVolumeMesh/Core/PropertyDefines.hh>
+//#include <OpenVolumeMesh/Geometry/VectorT.hh>
+//#include <OpenVolumeMesh/Mesh/TetrahedralGeometryKernel.hh>
+//#include <OpenVolumeMesh/Core/GeometryKernel.hh>
+//#include <OpenVolumeMesh/Attribs/StatusAttrib.hh>
+
+#include <OpenVolumeMesh/Core/Handles.hh>
 #include <OpenVolumeMesh/Core/BaseEntities.hh>
-#include <OpenVolumeMesh/Core/PropertyPtr.hh>
-#include <OpenVolumeMesh/Core/PropertyDefines.hh>
+#include <OpenVolumeMesh/Core/Properties/PropertyPtr.hh>
 #include <OpenVolumeMesh/Geometry/VectorT.hh>
 #include <OpenVolumeMesh/Mesh/TetrahedralGeometryKernel.hh>
 #include <OpenVolumeMesh/Core/GeometryKernel.hh>
-- 
GitLab