@@ -0,0 +1,2593 @@
+%0Aimport os%0Aimport subprocess%0Aimport tempfile%0A%0Aimport numpy as np%0A%0A%0Aclass ExactGeodesicMixin(object):%0A    %22%22%22Mixin for computing exact geodesic distance along surface%22%22%22%0A%0A    def exact_geodesic_distance(self, vertex):%0A        %22%22%22Compute exact geodesic distance along surface%0A%0A        - uses VTP geodesic algorithm%0A%0A        Parameters%0A        ----------%0A        - vertex : int or list of int%0A            index of vertex or vertices to compute geodesic distance from%0A        %22%22%22%0A        if isinstance(vertex, list):%0A            return np.vstack(self.exact_geodesic_distance(v) for v in vertex).min(0)%0A        else:%0A            return self.call_vtp_geodesic(vertex)%0A%0A    def call_vtp_geodesic(self, vertex):%0A        %22%22%22Compute geodesic distance using VTP method%0A%0A        - uses authors' implementation of %5BQin el al 2016%5D%0A%0A        Parameters%0A        ----------%0A        - vertex : int%0A            index of vertex to compute geodesic distance from%0A        %22%22%22%0A%0A        # path to VTP executable%0A        vtp_path = '/auto/k2/share/geodesic/VTP-linux/cmake-build-debug/VTP'%0A%0A        # initialize temporary files%0A        f_obj, tmp_obj_path = tempfile.mkstemp()%0A        f_output, tmp_output_path = tempfile.mkstemp()%0A%0A        # create object file%0A        self.export_to_obj_file(f_obj)%0A%0A        # run algorithm%0A        cmd = %5Bvtp_path, '-m', tmp_obj_path, '-s', str(vertex), '-o', tmp_output_path%5D%0A        subprocess.call(cmd)%0A%0A        # read output%0A        with open(tmp_output_path) as f:%0A            distances = np.array(f.read().split('%5Cn')%5B:-1%5D, dtype=float)%0A%0A        os.close(f_obj)%0A        os.close(f_output)%0A%0A        return distances%0A%0A    def export_to_obj_file(self, path_or_handle):%0A        %22%22%22export Surface to Wavefront obj for use by external programs%0A%0A        https://en.wikipedia.org/wiki/Wavefront_.obj_file%0A%0A        Parameters%0A        ----------%0A        - path_or_handle : str or file handle%0A            - location to write .obj file to%0A        %22%22%22%0A%0A        if isinstance(path_or_handle, str):%0A            with open(path_or_handle, 'w') as f:%0A                return self.export_to_obj_file(self, f)%0A%0A        else:%0A            path_or_handle.write('mtllib none.mtl%5Cn')%0A            path_or_handle.write('o hemi%5Cn')%0A%0A            for vertex in self.pts:%0A                path_or_handle.write('v ' + ' '.join(vertex.astype(str)) + '%5Cn')%0A%0A            path_or_handle.write('usemtl None%5Cn')%0A            path_or_handle.write('s off%5Cn')%0A%0A            for polygon in self.polys:%0A                polygon = polygon + 1%0A                path_or_handle.write('f ' + ' '.join(polygon.astype(str)) + '%5Cn')%0A

add exact geodesic capabilities