diff --git a/Makefile b/Makefile
index 12375c4..94c66fe 100644
--- a/Makefile
+++ b/Makefile
@@ -52,14 +52,15 @@ $(tmpdirbuild)/package_creation: $(tmpdirbuild)
@echo "********"
@echo "********"
@echo "\033[0m"
- @virtualenv --system-site-packages $(venv_dir)
+ @virtualenv --system-site-packages $(venv_dir) -p python3
@ . $(activate) && pip install --upgrade pip
@ . $(activate) && pip install --upgrade virtualenv
@ . $(activate) && pip install nose2
@ . $(activate) && echo `which pip` && pip -V
@ . $(activate) && pip install --upgrade setuptools && echo `which pip` && pip -V
@ . $(activate) && pip install --upgrade wheel && echo `which pip` && pip -V
- @ . $(activate) && pip install numpy scipy pyopengl pillow pyzmq pyyaml && echo `which pip` && pip -V
+ @ . $(activate) && pip install numpy
+ @ . $(activate) && pip install scipy pyopengl pillow pyzmq pyyaml && echo `which pip` && pip -V
####### PACKAGE: creating SDIST target
@echo "\033[0;33m----- [" ${package_name} "] Creating the source distribution\033[0m"
@ . $(activate) && python setup.py sdist
diff --git a/mesh/colors.py b/mesh/colors.py
index c456b63..281d86b 100644
--- a/mesh/colors.py
+++ b/mesh/colors.py
@@ -28,7 +28,7 @@ def main():
g = int(reg.group(2)) / 255.
b = int(reg.group(3)) / 255.
d = reg.group(4)
- print "'%s': np.array([%.2f, %.2f, %.2f])," % (d, r, g, b)
+ print("'%s': np.array([%.2f, %.2f, %.2f])," % (d, r, g, b))
line = fp.readline()
diff --git a/mesh/landmarks.py b/mesh/landmarks.py
index 0847d1e..ba812cc 100644
--- a/mesh/landmarks.py
+++ b/mesh/landmarks.py
@@ -47,7 +47,7 @@ def landm_xyz(self, ordering=None):
def recompute_landmark_indices(self, landmark_fname=None, safe_mode=True):
filtered_landmarks = dict(filter(lambda e, : e[1] != [0.0, 0.0, 0.0], self.landm_raw_xyz.items()) if (landmark_fname and safe_mode) else self.landm_raw_xyz.items())
if len(filtered_landmarks) != len(self.landm_raw_xyz):
- print "WARNING: %d landmarks in file %s are positioned at (0.0, 0.0, 0.0) and were ignored" % (len(self.landm_raw_xyz) - len(filtered_landmarks), landmark_fname)
+ print("WARNING: %d landmarks in file %s are positioned at (0.0, 0.0, 0.0) and were ignored" % (len(self.landm_raw_xyz) - len(filtered_landmarks), landmark_fname))
self.landm = {}
self.landm_regressors = {}
@@ -85,7 +85,7 @@ def set_landmarks_from_raw(self, landmarks):
if np.all(map(lambda x: hasattr(x, "__iter__") and len(x) == 3, landmarks.values())):
landmarks = dict((i, np.array(l)) for i, l in landmarks.items())
self.set_landmarks_from_xyz(landmarks)
- elif np.all(map(lambda x: isinstance(x, (int, long)), landmarks.values())):
+ elif np.all(map(lambda x: isinstance(x, int), landmarks.values())):
self.landm = landmarks
self.recompute_landmark_xyz()
else:
diff --git a/mesh/lines.py b/mesh/lines.py
index 5a51a6e..20ea9a5 100644
--- a/mesh/lines.py
+++ b/mesh/lines.py
@@ -5,7 +5,7 @@
# See file LICENSE.txt for full license details.
import numpy as np
-import colors
+from . import colors
class Lines(object):
diff --git a/mesh/mesh.py b/mesh/mesh.py
index bada11a..56859ca 100755
--- a/mesh/mesh.py
+++ b/mesh/mesh.py
@@ -13,10 +13,12 @@
import os
+from functools import reduce
+
import numpy as np
-import colors
-import search
+from . import colors
+from . import search
try:
from .serialization import serialization
@@ -153,7 +155,7 @@ def jet(v):
result[result < 0.0] = 0.0
return row(result)
color = col(color)
- color = np.concatenate([jet(color[i]) for i in xrange(color.size)], axis=0)
+ color = np.concatenate([jet(color[i]) for i in range(color.size)], axis=0)
return np.ones_like(arr) * color
diff --git a/mesh/meshviewer.py b/mesh/meshviewer.py
index d44a522..0c57891 100755
--- a/mesh/meshviewer.py
+++ b/mesh/meshviewer.py
@@ -90,8 +90,8 @@
# this block is below the previous one to make my linter happy
if __package__ is None:
- print "this file cannot be executed as a standalone python module"
- print "python -m psbody.mesh.%s arguments" % (os.path.splitext(os.path.basename(__file__))[0])
+ print("this file cannot be executed as a standalone python module")
+ print("python -m psbody.mesh.%s arguments" % (os.path.splitext(os.path.basename(__file__))[0]))
sys.exit(-1)
@@ -110,10 +110,10 @@ def _test_for_opengl():
# from OpenGL.GLUT import glutInit
glutInit()
except Exception as e:
- print >> sys.stderr, e
- print 'failure'
+ print(e, file=sys.stderr)
+ print('failure')
else:
- print 'success'
+ print('success')
test_for_opengl_cached = None
@@ -129,12 +129,12 @@ def test_for_opengl():
if test_for_opengl_cached is None:
p = _run_self(["TEST_FOR_OPENGL"], stderr=subprocess.PIPE)
p.wait()
- line = '\n'.join(p.stdout.readlines())
+ line = ''.join(str(p.stdout.readlines()))
test_for_opengl_cached = 'success' in line
if not test_for_opengl_cached:
- print 'OpenGL test failed: '
- print '\tstdout:', line
- print '\tstderr:', '\n'.join(p.stderr.readlines())
+ print('OpenGL test failed: ')
+ print('\tstdout:', line)
+ print('\tstderr:', '\n'.join(p.stderr.readlines()))
return test_for_opengl_cached
@@ -311,7 +311,7 @@ class MeshViewerLocal(object):
managed = {}
def __new__(cls, titlebar, uid, shape, keepalive, window_width, window_height):
- assert(uid is None or isinstance(uid, str) or isinstance(uid, unicode))
+ assert(uid is None or isinstance(uid, str))
if uid == 'stack':
uid = ''.join(traceback.format_list(traceback.extract_stack()))
@@ -325,7 +325,7 @@ def __new__(cls, titlebar, uid, shape, keepalive, window_width, window_height):
result.p = _run_self([titlebar, str(shape[0]), str(shape[1]), str(window_width), str(window_height)])
line = result.p.stdout.readline()
- current_port = re.match('(.*?)', line)
+ current_port = re.match('(.*?)', line.decode(sys.stdout.encoding))
if not current_port:
raise Exception("MeshViewer remote appears to have failed to launch")
current_port = int(current_port.group(1))
@@ -870,7 +870,7 @@ def __init__(self,
# Print out our port so that our client can connect to us with it. Flush stdout immediately; otherwise
# our client could wait forever.
- print '%d\n' % (port,)
+ print('%d\n' % (port,))
sys.stdout.flush()
self.arcball = ArcBallT(width, height)
@@ -1109,7 +1109,7 @@ def handle_request(self, request):
mv.autorecenter = obj
self.need_redraw = True
elif label == 'titlebar':
- assert(isinstance(obj, str) or isinstance(obj, unicode))
+ assert(isinstance(obj, str))
self.titlebar = obj
glutSetWindowTitle(obj)
elif label == 'lighting_on':
@@ -1119,7 +1119,7 @@ def handle_request(self, request):
glClearColor(obj[0], obj[1], obj[2], 1.0)
self.need_redraw = True
elif label == 'save_snapshot': # redraws for itself
- assert(isinstance(obj, str) or isinstance(obj, unicode))
+ assert(isinstance(obj, str))
self.snapshot(obj)
elif label == 'get_keypress':
self.keypress_port = obj
@@ -1213,7 +1213,7 @@ def init_opengl(self):
height=int(sys.argv[5]))
else:
- print "#" * 10
- print 'Usage:'
- print "python -m %s.%s arguments" % (__package__, os.path.splitext(os.path.basename(__file__))[0])
+ print("#" * 10)
+ print('Usage:')
+ print("python -m %s.%s arguments" % (__package__, os.path.splitext(os.path.basename(__file__))[0]))
sys.exit(-1)
diff --git a/mesh/search.py b/mesh/search.py
index 7d682ad..be85520 100644
--- a/mesh/search.py
+++ b/mesh/search.py
@@ -21,17 +21,18 @@
class AabbTree(object):
"""Encapsulates an AABB (Axis Aligned Bounding Box) Tree"""
def __init__(self, m):
- import spatialsearch
+ from . import spatialsearch
+ # this shit return NULL
self.cpp_handle = spatialsearch.aabbtree_compute(m.v.astype(np.float64).copy(order='C'), m.f.astype(np.uint32).copy(order='C'))
def nearest(self, v_samples, nearest_part=False):
"nearest_part tells you whether the closest point in triangle abc is in the interior (0), on an edge (ab:1,bc:2,ca:3), or a vertex (a:4,b:5,c:6)"
- import spatialsearch
+ from . import spatialsearch
f_idxs, f_part, v = spatialsearch.aabbtree_nearest(self.cpp_handle, np.array(v_samples, dtype=np.float64, order='C'))
return (f_idxs, f_part, v) if nearest_part else (f_idxs, v)
def nearest_alongnormal(self, points, normals):
- import spatialsearch
+ from . import spatialsearch
distances, f_idxs, v = spatialsearch.aabbtree_nearest_alongnormal(self.cpp_handle,
points.astype(np.float64),
normals.astype(np.float64))
@@ -57,7 +58,7 @@ def nearest_vertices(self, v_samples):
class CGALClosestPointTree(object):
"""Encapsulates an AABB (Axis Aligned Bounding Box) Tree """
def __init__(self, m):
- import spatialsearch
+ from . import spatialsearch
self.v = m.v
n = m.v.shape[0]
faces = np.vstack([np.array(range(n)), np.array(range(n)) + n, np.array(range(n)) + 2 * n]).T
@@ -65,12 +66,12 @@ def __init__(self, m):
self.cpp_handle = spatialsearch.aabbtree_compute(np.vstack([m.v + eps * np.array([1.0, 0.0, 0.0]), m.v + eps * np.array([0.0, 1.0, 0.0]), m.v - eps * np.array([1.0, 1.0, 0.0])]).astype(np.float64).copy(order='C'), faces.astype(np.uint32).copy(order='C'))
def nearest(self, v_samples):
- import spatialsearch
+ from . import spatialsearch
f_idxs, f_part, v = spatialsearch.aabbtree_nearest(self.cpp_handle, np.array(v_samples, dtype=np.float64, order='C'))
return (f_idxs.flatten(), (np.sum(((self.v[f_idxs.flatten()] - v_samples) ** 2.0), axis=1) ** 0.5).flatten())
def nearest_vertices(self, v_samples):
- import spatialsearch
+ from . import spatialsearch
f_idxs, f_part, v = spatialsearch.aabbtree_nearest(self.cpp_handle, np.array(v_samples, dtype=np.float64, order='C'))
return self.v[f_idxs.flatten()]
@@ -79,11 +80,11 @@ class AabbNormalsTree(object):
def __init__(self, m):
# the weight of the normals cosine is proportional to the std of the vertices
# the best point can be translated up to 2*eps because of the normals
- import aabb_normals
+ from . import aabb_normals
eps = 0.1 # np.std(m.v)#0
self.tree_handle = aabb_normals.aabbtree_n_compute(m.v, m.f.astype(np.uint32).copy(), eps)
def nearest(self, v_samples, n_samples):
- import aabb_normals
+ from . import aabb_normals
closest_tri, closest_p = aabb_normals.aabbtree_n_nearest(self.tree_handle, v_samples, n_samples)
return (closest_tri, closest_p)
diff --git a/mesh/serialization/serialization.py b/mesh/serialization/serialization.py
index 034db53..9503f6e 100755
--- a/mesh/serialization/serialization.py
+++ b/mesh/serialization/serialization.py
@@ -14,7 +14,6 @@
from ..errors import SerializationError
-
"""
serialization.py
@@ -26,6 +25,7 @@
'set_landmark_indices_from_ppfile', 'set_landmark_indices_from_lmrkfile',
'load_from_ply', 'load_from_file']
+
# import os.path
@@ -74,7 +74,7 @@ def load_from_obj(self, filename):
currLandm = line[1]
elif line[0] == 'mtllib':
self.materials_filepath = os.path.join(os.path.dirname(filename), line[1])
- self.materials_file = file(self.materials_filepath, 'r').readlines()
+ self.materials_file = open(self.materials_filepath, 'r').readlines()
self.v = np.array(v)
self.f = np.array(f) - 1
@@ -149,7 +149,8 @@ def write_face_to_obj_file(face_index, obj_file):
if not hasattr(self, 'fn'):
self.reset_face_normals()
normal_indices = self.fn[face_index][::ff] + 1
- obj_file.write('f %d/%d/%d %d/%d/%d %d/%d/%d\n' % tuple(np.array([vertex_indices, texture_indices, normal_indices]).T.flatten()))
+ obj_file.write('f %d/%d/%d %d/%d/%d %d/%d/%d\n' % tuple(
+ np.array([vertex_indices, texture_indices, normal_indices]).T.flatten()))
elif hasattr(self, 'fn'):
normal_indices = self.fn[face_index][::ff] + 1
obj_file.write('f %d//%d %d//%d %d//%d\n' % tuple(np.array([vertex_indices, normal_indices]).T.flatten()))
@@ -272,7 +273,9 @@ def write_three_json(self, filename, name=""):
mesh_data["vertices"] = self.v.flatten().tolist()
mesh_data["normals"] = self.vn.flatten().tolist()
mesh_data["uvs"] = [np.array([[vt[0], vt[1]] for vt in self.vt]).flatten().tolist()]
- mesh_data["faces"] = np.array([[42, self.f[i][0], self.f[i][1], self.f[i][2], 0, self.ft[i][0], self.ft[i][1], self.ft[i][2], self.fn[i][0], self.fn[i][1], self.fn[i][2]] for i in range(len(self.f))]).flatten().tolist()
+ mesh_data["faces"] = np.array([[42, self.f[i][0], self.f[i][1], self.f[i][2], 0, self.ft[i][0], self.ft[i][1],
+ self.ft[i][2], self.fn[i][0], self.fn[i][1], self.fn[i][2]] for i in
+ range(len(self.f))]).flatten().tolist()
json_or_js_file = open(filename, 'w')
json_or_js_file.write(json.dumps(mesh_data, indent=4))
@@ -422,13 +425,19 @@ def load_from_file(self, filename, use_cpp=True):
def load_from_ply(self, filename):
- import plyutils
+ from os.path import abspath, dirname, join
+
+ test_data_folder = abspath(join(dirname(__file__), '..', 'data', 'unittest'))
+
+ from psbody.mesh.serialization import plyutils
try:
res = plyutils.read(filename)
- except plyutils.error, e:
- raise SerializationError(e.message)
+ except plyutils.error as e:
+ raise SerializationError(e)
+
self.v = np.array(res['pts']).T.copy()
self.f = np.array(res['tri']).T.copy()
+
if 'color' in res:
self.set_vertex_colors(np.array(res['color']).T.copy() / 255)
if 'normals' in res:
diff --git a/mesh/src/aabb_normals.cpp b/mesh/src/aabb_normals.cpp
index f0431f8..4005269 100644
--- a/mesh/src/aabb_normals.cpp
+++ b/mesh/src/aabb_normals.cpp
@@ -35,18 +35,27 @@ static PyMethodDef SpatialsearchMethods[] = {
{NULL, NULL, 0, NULL} /* Sentinel */
};
+static struct PyModuleDef moduleDef =
+{
+ PyModuleDef_HEAD_INIT,
+ "aabb_normals", /* name of module */
+ "", /* module documentation, may be NULL */
+ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
+ SpatialsearchMethods
+};
-
-PyMODINIT_FUNC
-initaabb_normals(void)
+PyMODINIT_FUNC PyInit_aabb_normals(void)
{
- (void) Py_InitModule("aabb_normals", SpatialsearchMethods);
+ PyObject *module = PyModule_Create(&moduleDef);
+
import_array();
+
+ return module;
}
-void aabb_tree_destructor(void *ptr)
+void aabb_tree_destructor(PyObject *ptr)
{
- TreeAndTri* search = (TreeAndTri*)ptr;
+ TreeAndTri* search = (TreeAndTri*) PyCapsule_GetPointer(ptr, NULL);
delete search;
}
@@ -90,8 +99,8 @@ aabbtree_normals_compute(PyObject *self, PyObject *args)
{
TreeAndTri* search = new TreeAndTri(m_mesh_tri,m_mesh_points,eps,T,P);
- PyObject* result = PyCObject_FromVoidPtr((void*)search, aabb_tree_destructor);
- return Py_BuildValue("N", result);
+ PyObject* result = PyCapsule_New((void*)search, NULL, aabb_tree_destructor);
+ return result;
}
catch (mesh_aabb_tree_error&)
{
@@ -107,7 +116,7 @@ aabbtree_normals_nearest(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "OOO", &py_tree, &py_v, &py_n))
return NULL;
- TreeAndTri *search = (TreeAndTri *)PyCObject_AsVoidPtr(py_tree);
+ TreeAndTri *search = (TreeAndTri *) PyCapsule_GetPointer(py_tree, NULL);
npy_intp* v_dims = PyArray_DIMS(py_v);
npy_intp* n_dims = PyArray_DIMS(py_n);
@@ -174,7 +183,7 @@ aabbtree_normals_selfintersects(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O", &py_tree))
return NULL;
- TreeAndTri *search = (TreeAndTri *)PyCObject_AsVoidPtr(py_tree);
+ TreeAndTri *search = (TreeAndTri *) PyCapsule_GetPointer(py_tree, NULL);
for(Iterator it=search->triangles.begin();it!=search->triangles.end();++it)
if(search->tree.do_intersect(*it))
diff --git a/mesh/src/plyutils.c b/mesh/src/plyutils.c
index 7d3e17b..4d008d1 100644
--- a/mesh/src/plyutils.c
+++ b/mesh/src/plyutils.c
@@ -10,17 +10,27 @@ static PyMethodDef PlyutilsMethods[] = {
{NULL, NULL, 0, NULL}
};
+static struct PyModuleDef moduleDef =
+{
+ PyModuleDef_HEAD_INIT,
+ "serialization.plyutils", /* name of module */
+ "", /* module documentation, may be NULL */
+ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
+ PlyutilsMethods
+};
+
static PyObject *PlyutilsError;
-PyMODINIT_FUNC initplyutils(void) {
- PyObject *m;
- m = Py_InitModule("plyutils", PlyutilsMethods);
+PyMODINIT_FUNC PyInit_plyutils(void) {
+ PyObject *m = PyModule_Create(&moduleDef);
if (m == NULL)
- return;
+ return NULL;
PlyutilsError = PyErr_NewException("plyutils.error", NULL, NULL);
Py_INCREF(PlyutilsError);
PyModule_AddObject(m, "error", PlyutilsError);
+
+ return m;
}
int has_color(p_ply ply) {
@@ -109,8 +119,15 @@ static PyObject * plyutils_read(PyObject *self, PyObject *args)
tri = Py_BuildValue("[N,N,N]", PyList_New(n_faces), PyList_New(n_faces), PyList_New(n_faces));
if (!ply_read(ply)) {
- PyErr_SetString(PlyutilsError, "Read failed.");
- return NULL;
+ char * msg = "Read failed. ";
+ char* catString = malloc(strlen(msg)+strlen(filename)+1);
+ strcpy(catString, msg);
+ strcat(catString, filename);
+
+ PyErr_SetString(PlyutilsError, catString);
+ // use the string then delete it when you're done.
+ free(catString);
+ return NULL;
}
ply_close(ply);
@@ -160,7 +177,7 @@ static PyObject * plyutils_write(PyObject *self, PyObject *args)
res = 1;
for (ii = 0; ii < PyList_Size(comments); ++ii) {
- comment = PyString_AsString(PyObject_Str(PyList_GetItem(comments, ii)));
+ comment = PyBytes_AsString(PyObject_Str(PyList_GetItem(comments, ii)));
res &= ply_add_comment(ply, comment);
}
@@ -205,9 +222,9 @@ static PyObject * plyutils_write(PyObject *self, PyObject *args)
}
if(use_color){
row = PyList_GetItem(color, ii);
- res &= ply_write(ply, (unsigned char)PyInt_AsUnsignedLongMask(PyList_GetItem(row, 0)));
- res &= ply_write(ply, (unsigned char)PyInt_AsUnsignedLongMask(PyList_GetItem(row, 1)));
- res &= ply_write(ply, (unsigned char)PyInt_AsUnsignedLongMask(PyList_GetItem(row, 2)));
+ res &= ply_write(ply, (unsigned char)PyLong_AsUnsignedLongMask(PyList_GetItem(row, 0)));
+ res &= ply_write(ply, (unsigned char)PyLong_AsUnsignedLongMask(PyList_GetItem(row, 1)));
+ res &= ply_write(ply, (unsigned char)PyLong_AsUnsignedLongMask(PyList_GetItem(row, 2)));
}
}
if (!res) {
diff --git a/mesh/src/py_loadobj.cpp b/mesh/src/py_loadobj.cpp
index 69fa262..5ed2b46 100644
--- a/mesh/src/py_loadobj.cpp
+++ b/mesh/src/py_loadobj.cpp
@@ -39,17 +39,26 @@ static PyMethodDef loadobj_methods[] = {
{NULL, NULL, 0, NULL} /* Sentinel */
};
-PyMODINIT_FUNC
-initloadobj(void)
+static struct PyModuleDef moduleDef =
{
- PyObject *m = Py_InitModule("loadobj", loadobj_methods);
+ PyModuleDef_HEAD_INIT,
+ "serialization.loadobj", /* name of module */
+ "", /* module documentation, may be NULL */
+ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
+ loadobj_methods
+};
+
+PyMODINIT_FUNC PyInit_loadobj(void) {
+ PyObject *m = PyModule_Create(&moduleDef);
if (m == NULL)
- return;
+ return NULL;
import_array();
LoadObjError = PyErr_NewException(const_cast("loadobj.LoadObjError"), NULL, NULL);
Py_INCREF(LoadObjError);
PyModule_AddObject(m, "LoadObjError", LoadObjError);
+
+ return m;
}
static PyObject *
diff --git a/mesh/src/py_visibility.cpp b/mesh/src/py_visibility.cpp
index 1fdeecb..6c5ac0f 100644
--- a/mesh/src/py_visibility.cpp
+++ b/mesh/src/py_visibility.cpp
@@ -24,22 +24,34 @@ static PyMethodDef visibility_methods[] = {
{NULL, NULL, 0, NULL} /* Sentinel */
};
-PyMODINIT_FUNC
-initvisibility(void)
+
+
+static struct PyModuleDef moduleDef =
{
- PyObject *m = Py_InitModule("visibility", visibility_methods);
+ PyModuleDef_HEAD_INIT,
+ "psbody.mesh.visibility", /* name of module */
+ "", /* module documentation, may be NULL */
+ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
+ visibility_methods
+};
+
+PyMODINIT_FUNC PyInit_visibility(void)
+{
+ PyObject *m = PyModule_Create(&moduleDef);
if (m == NULL)
- return;
+ return NULL;
import_array();
VisibilityError = PyErr_NewException(const_cast("visibility.VisibilityError"), NULL, NULL);
Py_INCREF(VisibilityError);
PyModule_AddObject(m, "VisibilityError", VisibilityError);
+
+ return m;
}
-void visibility_destructor(void *ptr)
+void visibility_destructor(PyObject *ptr)
{
- TreeAndTri* search = (TreeAndTri*)ptr;
+ TreeAndTri* search = (TreeAndTri*) PyCapsule_GetPointer(ptr, NULL);
delete search;
}
@@ -90,7 +102,7 @@ visibility_compute(PyObject *self, PyObject *args, PyObject *keywds)
TreeAndTri* search;
if(py_tree != NULL){
- search = (TreeAndTri *)PyCObject_AsVoidPtr(py_tree);
+ search = (TreeAndTri *)PyCapsule_GetPointer(py_tree, NULL);
}
else{
@@ -187,8 +199,8 @@ visibility_compute(PyObject *self, PyObject *args, PyObject *keywds)
pSensors, min_dist, visibility, normal_dot_cam);
if(py_tree == NULL){
- PyObject* py_bin_visibility = PyCObject_FromVoidPtr((void*)search, visibility_destructor);
- PyObject* py_normal_dot_cam = PyCObject_FromVoidPtr((void*)search, visibility_destructor);
+ PyObject* py_bin_visibility = PyCapsule_New((void*)search, NULL, visibility_destructor);
+ PyObject* py_normal_dot_cam = PyCapsule_New((void*)search, NULL, visibility_destructor);
}
return Py_BuildValue("NN",py_bin_visibility, py_normal_dot_cam);
diff --git a/mesh/src/spatialsearchmodule.cpp b/mesh/src/spatialsearchmodule.cpp
index ec982b8..dde2918 100644
--- a/mesh/src/spatialsearchmodule.cpp
+++ b/mesh/src/spatialsearchmodule.cpp
@@ -21,35 +21,34 @@ using namespace tbb;
typedef uint32_t Index;
-static PyObject *
-spatialsearch_aabbtree_compute(PyObject *self, PyObject *args);
+static PyObject* spatialsearch_aabbtree_compute(PyObject *self, PyObject *args);
-static PyObject *
-spatialsearch_aabbtree_nearest(PyObject *self, PyObject *args);
+static PyObject* spatialsearch_aabbtree_nearest(PyObject *self, PyObject *args);
-static PyObject *
-spatialsearch_aabbtree_nearest_alongnormal(PyObject *self, PyObject *args);
+static PyObject* spatialsearch_aabbtree_nearest_alongnormal(PyObject *self, PyObject *args);
static PyObject *Mesh_IntersectionsError;
static PyMethodDef SpatialsearchMethods[] = {
- {"aabbtree_compute", spatialsearch_aabbtree_compute, METH_VARARGS,
- "aabbtree_compute."},
- {"aabbtree_nearest", spatialsearch_aabbtree_nearest, METH_VARARGS,
- "aabbtree_nearest."},
- {"aabbtree_nearest_alongnormal", spatialsearch_aabbtree_nearest_alongnormal, METH_VARARGS,
- "aabbtree_nearest."},
+ {"aabbtree_compute", spatialsearch_aabbtree_compute, METH_VARARGS, "aabbtree_compute."},
+ {"aabbtree_nearest", spatialsearch_aabbtree_nearest, METH_VARARGS, "aabbtree_nearest."},
+ {"aabbtree_nearest_alongnormal", spatialsearch_aabbtree_nearest_alongnormal, METH_VARARGS, "aabbtree_nearest."},
{NULL, NULL, 0} /* Sentinel */
};
+static struct PyModuleDef moduleDef = {
+ PyModuleDef_HEAD_INIT,
+ "spatialsearch", /* name of module */
+ "", /* module documentation, may be NULL */
+ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
+ SpatialsearchMethods
+};
+PyMODINIT_FUNC PyInit_spatialsearch(void) {
-PyMODINIT_FUNC
-initspatialsearch(void)
-{
- PyObject *m = Py_InitModule("spatialsearch", SpatialsearchMethods);
+ PyObject *m = PyModule_Create(&moduleDef);
if (m == NULL) {
- return;
+ return NULL;
}
import_array();
@@ -58,19 +57,21 @@ initspatialsearch(void)
Mesh_IntersectionsError = PyErr_NewException(const_cast("spatialsearch.Mesh_IntersectionsError"), NULL, NULL);
Py_INCREF(Mesh_IntersectionsError);
PyModule_AddObject(m, "Mesh_IntersectionsError", Mesh_IntersectionsError);
+
+ return m;
}
-void aabb_tree_destructor(void *ptr)
+void aabb_tree_destructor(PyObject *ptr)
{
- TreeAndTri* search = (TreeAndTri*)ptr;
+ TreeAndTri* search = (TreeAndTri*) PyCapsule_GetPointer(ptr, NULL);
delete search;
}
static PyObject *
spatialsearch_aabbtree_compute(PyObject *self, PyObject *args)
{
- PyArrayObject *py_v = NULL, *py_f = NULL;
+ PyArrayObject *py_v = NULL, *py_f = NULL; // numpy memory copy, probably managed by python
if (!PyArg_ParseTuple(args, "O!O!", &PyArray_Type, &py_v,&PyArray_Type, &py_f))
return NULL;
@@ -118,8 +119,8 @@ spatialsearch_aabbtree_compute(PyObject *self, PyObject *args)
search->tree.rebuild(search->triangles.begin(), search->triangles.end());
search->tree.accelerate_distance_queries();
- PyObject* result = PyCObject_FromVoidPtr((void*)search, aabb_tree_destructor);
- return Py_BuildValue("N", result);
+ PyObject* result = PyCapsule_New((void*)search, NULL, aabb_tree_destructor);
+ return result;
}
void spatialsearch_aabbtree_nearest_one(int ss, TreeAndTri * search, std::vector &sample_points,
@@ -144,8 +145,8 @@ class AaBbTreeNearestTbb {
uint32_t* closest_part;
array* closest_point;
public:
- void operator()( const blocked_range& r ) const {
- for( size_t i=r.begin(); i!=r.end(); ++i )
+ void operator()(const blocked_range& r) const {
+ for (size_t i=r.begin(); i!=r.end(); ++i)
spatialsearch_aabbtree_nearest_one(i, search, *sample_points, closest_triangles, closest_part, closest_point);
}
AaBbTreeNearestTbb( TreeAndTri * search, std::vector *sample_points,
@@ -158,13 +159,12 @@ class AaBbTreeNearestTbb {
#endif
-static PyObject *
-spatialsearch_aabbtree_nearest(PyObject *self, PyObject *args)
+static PyObject* spatialsearch_aabbtree_nearest(PyObject *self, PyObject *args)
{
PyObject *py_tree, *py_v;
if (!PyArg_ParseTuple(args, "OO!", &py_tree, &PyArray_Type, &py_v))
return NULL;
- TreeAndTri *search = (TreeAndTri *)PyCObject_AsVoidPtr(py_tree);
+ TreeAndTri *search = (TreeAndTri *) PyCapsule_GetPointer(py_tree, NULL);
npy_intp* v_dims = PyArray_DIMS(py_v);
@@ -201,25 +201,24 @@ spatialsearch_aabbtree_nearest(PyObject *self, PyObject *args)
#ifdef HAVE_TBB
- parallel_for(blocked_range(0,S), AaBbTreeNearestTbb(search, &sample_points, closest_triangles, closest_part, closest_point));
+ parallel_for(blocked_range(0,S), AaBbTreieNearestTbb(search, &sample_points, closest_triangles, closest_part, closest_point));
#else
#ifdef HAVE_OPENMP
#pragma omp parallel for
#endif
- for(size_t ss=0; ss* p_arr=reinterpret_cast*>(PyArray_DATA(py_p));
- array* n_arr=reinterpret_cast*>(PyArray_DATA(py_n));
+ array* p_arr = reinterpret_cast*>(PyArray_DATA(py_p));
+ array* n_arr = reinterpret_cast*>(PyArray_DATA(py_n));
#ifdef _OPENMP
omp_set_num_threads(8);
@@ -242,7 +241,7 @@ spatialsearch_aabbtree_nearest_alongnormal(PyObject *self, PyObject *args)
std::vector n_v;
p_v.reserve(S);
n_v.reserve(S);
- for(size_t ss=0; ss(PyArray_DATA(result1));
+ double* distance = reinterpret_cast(PyArray_DATA(result1));
PyObject *result2 = PyArray_SimpleNew(1, result1_dims, NPY_UINT32);
- uint32_t* closest_triangles=reinterpret_cast(PyArray_DATA(result2));
+ uint32_t* closest_triangles = reinterpret_cast(PyArray_DATA(result2));
npy_intp result3_dims[] = {S, 3};
PyObject *result3 = PyArray_SimpleNew(2, result3_dims, NPY_DOUBLE);
diff --git a/mesh/topology/decimation.py b/mesh/topology/decimation.py
index 3f7b9bf..fe4cfb3 100644
--- a/mesh/topology/decimation.py
+++ b/mesh/topology/decimation.py
@@ -144,7 +144,7 @@ def collapse_cost(Qv, r, c, v):
cost = collapse_cost(Qv, r, c, mesh.v)
if cost['collapse_cost'] > e[0]:
heapq.heappush(queue, (cost['collapse_cost'], e[1]))
- # print 'found outdated cost, %.2f < %.2f' % (e[0], cost['collapse_cost'])
+ # print('found outdated cost, %.2f < %.2f' % (e[0], cost['collapse_cost']))
continue
else:
diff --git a/setup.py b/setup.py
index d311efb..3b45793 100644
--- a/setup.py
+++ b/setup.py
@@ -92,7 +92,7 @@ def finalize_options(self):
self.set_undefined_options('install', ('boost_location', 'boost_location'),)
if self.boost_location is not None and self.boost_location.strip():
- # avoid empty folder name as it may happen and mess the compiler
+ # avoid empty folder name as it may happen and mess with the compiler
#
# we cannot assert that boost_location exist here, because we are
# running this code for targets that do not require compilation
@@ -113,8 +113,13 @@ def build_extension(self, ext):
ext.include_dirs += [os.path.join(os.path.abspath(self.build_temp), 'CGAL-4.7', 'include')]
if self.boost_location is not None:
ext.include_dirs += [self.boost_location]
+
# Remove empty paths
- ext.include_dirs = filter(None, ext.include_dirs)
+ filtered = []
+ for in_dir in filter(None, ext.include_dirs):
+ filtered.append(in_dir)
+ ext.include_dirs = filtered
+
return _build_ext.build_extension(self, ext)
def run(self):
diff --git a/tests/test_meshviewer.py b/tests/test_meshviewer.py
index f815bdd..0373f69 100644
--- a/tests/test_meshviewer.py
+++ b/tests/test_meshviewer.py
@@ -22,7 +22,7 @@ class TestMeshViewer(unittest.TestCase):
def setUp(self):
fnames = [os.path.join(test_data_folder, i) for i in os.listdir(test_data_folder) if os.path.splitext(i)[1].lower() == '.ply']
- self.meshes = [Mesh(filename=fnames[i]) for i in range(4)]
+ self.meshes = [Mesh(filename=fname) for fname in fnames]
def test_launch_smoke_test(self):
"""this test just opens a mesh window, waits, and kills the window"""
@@ -36,9 +36,9 @@ def test_launch_smoke_test(self):
sphere = Mesh(filename=os.path.join(test_data_folder, 'sphere.ply'))
sphere.v = sphere.v / 10.
- print 'keeping MeshViewer alive for 10 seconds..'
+ print('keeping MeshViewer alive for 10 seconds..')
time.sleep(10)
- print 'killing MeshViewer and exiting...'
+ print('killing MeshViewer and exiting...')
if 0:
# this cannot be unit tested
@@ -49,8 +49,8 @@ def test_launch_smoke_test(self):
sphere.v = sphere.v - row(np.mean(sphere.v, axis=0)) + row(np.array([click['x'], click['y'], click['z']]))
mvs[subwin_row][subwin_col].set_dynamic_meshes([sphere])
- print 'items in mouseclick dict are as follows:'
- print click
+ print('items in mouseclick dict are as follows:')
+ print(click)
@unittest.skipUnless(has_pil, "skipping test that requires Pillow")
def test_snapshot(self):