From 558d848e5895366a8f76e187f2b55ba1f98580f5 Mon Sep 17 00:00:00 2001 From: Kramer84 Date: Fri, 4 Oct 2024 20:18:32 +0200 Subject: [PATCH] Exposed simplify_mesh_lossless / tests required to see if advantages --- pyfqmr/Simplify.pyx | 82 +++++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/pyfqmr/Simplify.pyx b/pyfqmr/Simplify.pyx index 188262b..26ef51f 100644 --- a/pyfqmr/Simplify.pyx +++ b/pyfqmr/Simplify.pyx @@ -17,18 +17,19 @@ class _hidden_ref(object): self.faces = None self.verts = None -_REF = _hidden_ref() +_REF = _hidden_ref() cdef extern from "Simplify.h" namespace "Simplify" : - void simplify_mesh( int target_count, int update_rate, double aggressiveness, - bool verbose, int max_iterations,double alpha, int K, + void simplify_mesh( int target_count, int update_rate, double aggressiveness, + bool verbose, int max_iterations,double alpha, int K, bool lossless, double threshold_lossless, bool preserve_border) + void simplify_mesh_lossless(bool verbose, double epsilon, int max_iterations) void setMeshFromExt(vector[vector[double]] vertices, vector[vector[int]] faces) vector[vector[int]] getFaces() vector[vector[double]] getVertices() vector[vector[double]] getNormals() -cdef class Simplify : +cdef class Simplify : cdef int[:,:] faces_mv cdef double[:,:] vertices_mv @@ -37,7 +38,7 @@ cdef class Simplify : cdef vector[vector[int]] triangles_cpp cdef vector[vector[double]] vertices_cpp cdef vector[vector[double]] normals_cpp - + def __cinit__(self): pass @@ -82,7 +83,7 @@ cdef class Simplify : cpdef void setMesh(self, vertices, faces, face_colors=None): """Method to set the mesh of the simplifier object. - + Arguments --------- vertices : numpy.ndarray @@ -93,7 +94,7 @@ cdef class Simplify : array of face_colors of shape (n_faces,3) this is not yet implemented """ - _REF.faces = faces + _REF.faces = faces _REF.verts = vertices # We have to clear the vectors to avoid overflow when using the simplify object # multiple times @@ -107,9 +108,9 @@ cdef class Simplify : self.vertices_cpp = setVerticesNogil(self.vertices_mv, self.vertices_cpp) setMeshFromExt(self.vertices_cpp, self.triangles_cpp) - cpdef void simplify_mesh(self, int target_count = 100, int update_rate = 5, - double aggressiveness=7., max_iterations = 100, bool verbose=True, - bool lossless = False, double threshold_lossless=1e-3, double alpha = 1e-9, + cpdef void simplify_mesh(self, int target_count = 100, int update_rate = 5, + double aggressiveness=7., max_iterations = 100, bool verbose=True, + bool lossless = False, double threshold_lossless=1e-3, double alpha = 1e-9, int K = 3, bool preserve_border = True): """Simplify mesh @@ -118,23 +119,23 @@ cdef class Simplify : target_count : int Target number of triangles, not used if lossless is True update_rate : int - Number of iterations between each update. + Number of iterations between each update. If lossless flag is set to True, rate is 1 aggressiveness : float - Parameter controlling the growth rate of the threshold at each - iteration when lossless is False. + Parameter controlling the growth rate of the threshold at each + iteration when lossless is False. max_iterations : int - Maximal number of iterations + Maximal number of iterations verbose : bool control verbosity lossless : bool - Use the lossless simplification method + Use the lossless simplification method threshold_lossless : float - Maximal error after which a vertex is not deleted, only for - lossless method. - alpha : float + Maximal error after which a vertex is not deleted, only for + lossless method. + alpha : float Parameter for controlling the threshold growth - K : int + K : int Parameter for controlling the thresold growth preserve_border : Bool Flag for preserving vertices on open border @@ -155,21 +156,52 @@ cdef class Simplify : round(t_end-t_start,4), N_start, N_end) ) + cpdef void simplify_mesh_lossless(self, bool verbose = True, double epsilon=1e-3, int max_iterations=9999): + """Simplify mesh using lossless method + + Parameters + ---------- + verbose : bool + Control verbosity + epsilon : float + Maximal error after which a vertex is not deleted, controlling the precision + of the lossless simplification. + max_iterations : int + Maximum number of iterations to perform the simplification. + + Note + ---- + This function simplifies the mesh while preserving vertex positions + within the specified error tolerance (`epsilon`). The process continues + until either the `max_iterations` is reached or no further simplifications + can be made within the specified tolerance. + """ + N_start = self.faces_mv.shape[0] + t_start = _time() + simplify_mesh_lossless(verbose, epsilon, max_iterations) + t_end = _time() + N_end = getFaces().size() + + if verbose: + print('simplified mesh in {} seconds from {} to {} triangles'.format( + round(t_end-t_start,4), N_start, N_end) + ) + @cython.boundscheck(False) @cython.wraparound(False) # turn off negative index wrapping for entire function @cython.nonecheck(False) cdef vector[vector[double]] setVerticesNogil(double[:,:] vertices, vector[vector[double]] vector_vertices )nogil: """nogil function for filling the vector of vertices, "vector_vertices", - with the data found in the memory view of the array "vertices" + with the data found in the memory view of the array "vertices" """ - cdef vector[double] vertex + cdef vector[double] vertex vector_vertices.reserve(vertices.shape[0]) cdef size_t i = 0 cdef size_t j = 0 for i in range(vertices.shape[0]): vertex.clear() - for j in range(3): + for j in range(3): vertex.push_back(vertices[i,j]) vector_vertices.push_back(vertex) return vector_vertices @@ -181,14 +213,14 @@ cdef vector[vector[int]] setFacesNogil(int[:,:] faces, vector[vector[int]] vecto """nogil function for filling the vector of faces, "vector_faces", with the data found in the memory view of the array "faces" """ - cdef vector[int] triangle + cdef vector[int] triangle vector_faces.reserve(faces.shape[0]); cdef size_t i = 0 cdef size_t j = 0 for i in range(faces.shape[0]): triangle.clear() - for j in range(3): + for j in range(3): triangle.push_back(faces[i,j]) vector_faces.push_back(triangle) return vector_faces @@ -221,4 +253,4 @@ verts, faces = mesh.vertices, mesh.faces simpl.setMesh(verts, faces) simpl.getMesh() faces.shape -""" \ No newline at end of file +"""